Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/libexec/httpd - move special files defines into bozohttpd.h, ...



details:   https://anonhg.NetBSD.org/src/rev/1da15c71ae8f
branches:  trunk
changeset: 837152:1da15c71ae8f
user:      mrg <mrg%NetBSD.org@localhost>
date:      Wed Nov 21 09:37:02 2018 +0000

description:
- move special files defines into bozohttpd.h, so we can ...
- consolidate all the special file checks into
  bozo_check_special_files() so that all builds check the same
  list of special files, regardless of build options.
- convert "(void)bozo_http_error(...); return -1;" into plain
  "return bozo_http_error(...);"
- fix the call to bozo_check_special_files() to be used on all
  input types.  part of the fixes for failure to reject access
  to /.htpasswd as reported by JP on tech-security.
- use warn_unused_result attribute on bozo_check_special_files(),
  and fix the failures to return failure.  second part of the
  htpasswd access fix.
- update testsuite to use a fixed fake hostname.

call this bozohttpd 20181121.

diffstat:

 libexec/httpd/CHANGES                |   5 +-
 libexec/httpd/auth-bozo.c            |  19 +-------
 libexec/httpd/bozohttpd.c            |  83 +++++++++++++----------------------
 libexec/httpd/bozohttpd.h            |  32 ++++++++++++-
 libexec/httpd/testsuite/Makefile     |   7 +-
 libexec/httpd/testsuite/html_cmp     |   1 +
 libexec/httpd/testsuite/test-bigfile |  15 +++---
 libexec/httpd/testsuite/test-simple  |   5 +-
 8 files changed, 79 insertions(+), 88 deletions(-)

diffs (truncated from 415 to 300 lines):

diff -r e6517e406945 -r 1da15c71ae8f libexec/httpd/CHANGES
--- a/libexec/httpd/CHANGES     Wed Nov 21 08:55:05 2018 +0000
+++ b/libexec/httpd/CHANGES     Wed Nov 21 09:37:02 2018 +0000
@@ -1,6 +1,6 @@
-$NetBSD: CHANGES,v 1.27 2018/11/20 01:06:46 mrg Exp $
+$NetBSD: CHANGES,v 1.28 2018/11/21 09:37:02 mrg Exp $
 
-changes in bozohttpd 20181118:
+changes in bozohttpd 20181121:
        o  add url remap support via .bzremap file, from martin%netbsd.org@localhost
        o  handle redirections for any protocol, not just http:
        o  fix a denial of service attack against header contents, which
@@ -9,6 +9,7 @@
           initial line, each header, and the total time spent
        o  add -T option to expose new timeout settings
        o  minor RFC fixes related to timeout handling
+       o  fix special file (.htpasswd, .bz*) bypass.  reported by JP.
 
 changes in bozohttpd 20170201:
        o  fix an infinite loop in cgi processing
diff -r e6517e406945 -r 1da15c71ae8f libexec/httpd/auth-bozo.c
--- a/libexec/httpd/auth-bozo.c Wed Nov 21 08:55:05 2018 +0000
+++ b/libexec/httpd/auth-bozo.c Wed Nov 21 09:37:02 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: auth-bozo.c,v 1.20 2018/11/20 01:06:46 mrg Exp $       */
+/*     $NetBSD: auth-bozo.c,v 1.21 2018/11/21 09:37:02 mrg Exp $       */
 
 /*     $eterna: auth-bozo.c,v 1.17 2011/11/18 09:21:15 mrg Exp $       */
 
@@ -42,10 +42,6 @@
 
 #include "bozohttpd.h"
 
-#ifndef AUTH_FILE
-#define AUTH_FILE              ".htpasswd"
-#endif
-
 static ssize_t base64_decode(const unsigned char *, size_t,
                            unsigned char *, size_t);
 
@@ -68,7 +64,6 @@
                strcpy(dir, ".");
        else {
                *basename++ = '\0';
-                       /* ensure basename(file) != AUTH_FILE */
                if (bozo_check_special_files(request, basename))
                        return 1;
        }
@@ -173,18 +168,6 @@
        return 0;
 }
 
-int
-bozo_auth_check_special_files(bozo_httpreq_t *request,
-                               const char *name)
-{
-       bozohttpd_t *httpd = request->hr_httpd;
-
-       if (strcmp(name, AUTH_FILE) == 0)
-               return bozo_http_error(httpd, 403, request,
-                               "no permission to open authfile");
-       return 0;
-}
-
 void
 bozo_auth_check_401(bozo_httpreq_t *request, int code)
 {
diff -r e6517e406945 -r 1da15c71ae8f libexec/httpd/bozohttpd.c
--- a/libexec/httpd/bozohttpd.c Wed Nov 21 08:55:05 2018 +0000
+++ b/libexec/httpd/bozohttpd.c Wed Nov 21 09:37:02 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: bozohttpd.c,v 1.90 2018/11/20 01:06:46 mrg Exp $       */
+/*     $NetBSD: bozohttpd.c,v 1.91 2018/11/21 09:37:02 mrg Exp $       */
 
 /*     $eterna: bozohttpd.c,v 1.178 2011/11/18 09:21:15 mrg Exp $      */
 
@@ -109,25 +109,8 @@
 #define INDEX_HTML             "index.html"
 #endif
 #ifndef SERVER_SOFTWARE
-#define SERVER_SOFTWARE                "bozohttpd/20181119"
-#endif
-#ifndef DIRECT_ACCESS_FILE
-#define DIRECT_ACCESS_FILE     ".bzdirect"
-#endif
-#ifndef REDIRECT_FILE
-#define REDIRECT_FILE          ".bzredirect"
+#define SERVER_SOFTWARE                "bozohttpd/20181121"
 #endif
-#ifndef ABSREDIRECT_FILE
-#define ABSREDIRECT_FILE       ".bzabsredirect"
-#endif
-#ifndef REMAP_FILE
-#define REMAP_FILE             ".bzremap"
-#endif
-
-/*
- * When you add some .bz* file, make sure to also check it in
- * bozo_check_special_files()
- */
 
 #ifndef PUBLIC_HTML
 #define PUBLIC_HTML            "public_html"
@@ -696,7 +679,6 @@
        sa.sa_flags = 0;
        sigaction(SIGALRM, &sa, NULL);
 
-       
        if (clock_gettime(CLOCK_MONOTONIC, &ots) != 0) {
                (void)bozo_http_error(httpd, 500, NULL,
                        "clock_gettime failed");
@@ -1466,32 +1448,33 @@
         * if this pathname is really a directory, but doesn't end in /,
         * use it as the directory to look for the redir file.
         */
-       if((size_t)snprintf(dir, sizeof(dir), "%s", request->hr_file + 1) >=
-         sizeof(dir)) {
-               bozo_http_error(httpd, 404, request,
+       if ((size_t)snprintf(dir, sizeof(dir), "%s", request->hr_file + 1) >=
+         sizeof(dir))
+               return bozo_http_error(httpd, 404, request,
                  "file path too long");
-               return -1;
-       }
        debug((httpd, DEBUG_FAT, "check_bzredirect: dir %s", dir));
        basename = strrchr(dir, '/');
 
        if ((!basename || basename[1] != '\0') &&
            lstat(dir, &sb) == 0 && S_ISDIR(sb.st_mode)) {
                strcpy(path, dir);
+               basename = dir;
        } else if (basename == NULL) {
                strcpy(path, ".");
                strcpy(dir, "");
+               basename = request->hr_file + 1;
        } else {
                *basename++ = '\0';
-               bozo_check_special_files(request, basename);
                strcpy(path, dir);
        }
+       if (bozo_check_special_files(request, basename))
+               return -1;
 
        debug((httpd, DEBUG_FAT, "check_bzredirect: path %s", path));
 
        if ((size_t)snprintf(redir, sizeof(redir), "%s/%s", path,
          REDIRECT_FILE) >= sizeof(redir)) {
-               bozo_http_error(httpd, 404, request,
+               return bozo_http_error(httpd, 404, request,
                    "redirectfile path too long");
                return -1;
        }
@@ -1502,9 +1485,8 @@
        } else {
                if((size_t)snprintf(redir, sizeof(redir), "%s/%s", path,
                  ABSREDIRECT_FILE) >= sizeof(redir)) {
-                       bozo_http_error(httpd, 404, request,
+                       return bozo_http_error(httpd, 404, request,
                          "redirectfile path too long");
-                       return -1;
                }
                if (lstat(redir, &sb) < 0 || !S_ISLNK(sb.st_mode))
                        return 0;
@@ -1528,9 +1510,8 @@
        if (!absolute && redirpath[0] != '/') {
                if ((size_t)snprintf(finalredir = redir, sizeof(redir), "%s%s/%s",
                  (strlen(dir) > 0 ? "/" : ""), dir, redirpath) >= sizeof(redir)) {
-                       bozo_http_error(httpd, 404, request,
+                       return bozo_http_error(httpd, 404, request,
                          "redirect path too long");
-                       return -1;
                }
        } else
                finalredir = redirpath;
@@ -1566,21 +1547,15 @@
                debug((httpd, DEBUG_EXPLODING,
                        "fu_%%: got s == %%, s[1]s[2] == %c%c",
                        s[1], s[2]));
-               if (s[1] == '\0' || s[2] == '\0') {
-                       (void)bozo_http_error(httpd, 400, request,
+               if (s[1] == '\0' || s[2] == '\0')
+                       return bozo_http_error(httpd, 400, request,
                            "percent hack missing two chars afterwards");
-                       return 1;
-               }
-               if (s[1] == '0' && s[2] == '0') {
-                       (void)bozo_http_error(httpd, 404, request,
-                                       "percent hack was %00");
-                       return 1;
-               }
-               if (s[1] == '2' && s[2] == 'f') {
-                       (void)bozo_http_error(httpd, 404, request,
-                                       "percent hack was %2f (/)");
-                       return 1;
-               }
+               if (s[1] == '0' && s[2] == '0')
+                       return bozo_http_error(httpd, 404, request,
+                           "percent hack was %00");
+               if (s[1] == '2' && s[2] == 'f')
+                       return bozo_http_error(httpd, 404, request,
+                           "percent hack was %2f (/)");
 
                buf[0] = *++s;
                buf[1] = *++s;
@@ -1589,11 +1564,9 @@
                *t = (char)strtol(buf, NULL, 16);
                debug((httpd, DEBUG_EXPLODING,
                                "fu_%%: strtol put '%02x' into *t", *t));
-               if (*t++ == '\0') {
-                       (void)bozo_http_error(httpd, 400, request,
-                                       "percent hack got a 0 back");
-                       return 1;
-               }
+               if (*t++ == '\0')
+                       return bozo_http_error(httpd, 400, request,
+                           "percent hack got a 0 back");
 
                while (*s && *s != '%') {
                        if (end && s >= end)
@@ -1685,7 +1658,9 @@
        switch (check_bzredirect(request)) {
        case -1:
                goto bad_done;
-       case 1:
+       case 0:
+               break;
+       default:
                return 0;
        }
 
@@ -1963,7 +1938,11 @@
        if (strcmp(name, REMAP_FILE) == 0)
                return bozo_http_error(httpd, 403, request,
                    "no permission to open redirect file");
-       return bozo_auth_check_special_files(request, name);
+       if (strcmp(name, AUTH_FILE) == 0)
+               return bozo_http_error(httpd, 403, request,
+                   "no permission to open authfile");
+
+       return 0;
 }
 
 /* generic header printing routine */
diff -r e6517e406945 -r 1da15c71ae8f libexec/httpd/bozohttpd.h
--- a/libexec/httpd/bozohttpd.h Wed Nov 21 08:55:05 2018 +0000
+++ b/libexec/httpd/bozohttpd.h Wed Nov 21 09:37:02 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: bozohttpd.h,v 1.54 2018/11/20 01:23:06 mrg Exp $       */
+/*     $NetBSD: bozohttpd.h,v 1.55 2018/11/21 09:37:02 mrg Exp $       */
 
 /*     $eterna: bozohttpd.h,v 1.39 2011/11/18 09:21:15 mrg Exp $       */
 
@@ -217,9 +217,11 @@
 #if (defined(__GNUC__) && __GNUC__ >= 3) || defined(__lint__)
 #define BOZO_PRINTFLIKE(x,y) __attribute__((__format__(__printf__, x,y)))
 #define BOZO_DEAD __attribute__((__noreturn__))
+#define BOZO_CHECKRET __attribute__((__warn_unused_result__))
 #else
 #define BOZO_PRINTFLIKE(x,y)
 #define BOZO_DEAD
+#define BOZO_CHECKRET
 #endif
 
 #ifdef NO_DEBUG
@@ -231,9 +233,33 @@
 #define have_debug     (1)
 #endif /* NO_DEBUG */
 
+/*
+ * bozohttpd special files.  avoid serving these out.
+ *
+ * When you add some .bz* file, make sure to also check it in
+ * bozo_check_special_files()
+ */
+
+#ifndef DIRECT_ACCESS_FILE
+#define DIRECT_ACCESS_FILE     ".bzdirect"
+#endif
+#ifndef REDIRECT_FILE
+#define REDIRECT_FILE          ".bzredirect"
+#endif
+#ifndef ABSREDIRECT_FILE
+#define ABSREDIRECT_FILE       ".bzabsredirect"
+#endif
+#ifndef REMAP_FILE
+#define REMAP_FILE             ".bzremap"
+#endif
+#ifndef AUTH_FILE
+#define AUTH_FILE              ".htpasswd"
+#endif
+
+/* 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 *);
+int    bozo_check_special_files(bozo_httpreq_t *, const char *) BOZO_CHECKRET;
 char   *bozo_http_date(char *, size_t);
 void   bozo_print_header(bozo_httpreq_t *, struct stat *, const char *,
                          const char *);
@@ -284,7 +310,6 @@



Home | Main Index | Thread Index | Old Index