[hackers] [quark] change the behavior of docroot || Ivan Delalande

From: <git_AT_suckless.org>
Date: Sun, 30 Nov 2014 23:35:16 +0100

commit e42bb278462a965604525746160c6a9d2b08bef2
Author: Ivan Delalande <colona_AT_ycc.fr>
Date: Sun Nov 30 14:37:28 2014 +0100

    change the behavior of docroot
    
    Change the behavior of docroot, which is now used as a prefix path for
    all file operations related to static files. And add chrootdir, which is
    just the old docroot behavior and allows to control the path into which
    quark will chroot.
    
    Not having properly distinct configuration variables for chroot,
    document root and CGI root was specially annoying since commit 2822488
    which allowed users to retrieve the CGI script or binary by just
    guessing its path, since quark was chrooting into docroot before
    anything else, and thus the CGI script/binary was in the user accessible
    path.
    
    This is implemented by moving the reqbuf buffer in the middle of a
    bigger buffer, reqpath. That buffer contains the value of docroot at its
    beginning and reqbuf simply points to the first byte after this value.

diff --git a/config.def.h b/config.def.h
index 35ee857..716fb0d 100644
--- a/config.def.h
+++ b/config.def.h
_AT_@ -2,6 +2,7 @@
 
 static const char *servername = "127.0.0.1";
 static const char *serverport = "80";
+static const char *chrootdir = ".";
 static const char *docroot = ".";
 static const char *docindex = "index.html";
 static const char *user = "nobody";
diff --git a/quark.1 b/quark.1
index ceee081..35f854c 100644
--- a/quark.1
+++ b/quark.1
_AT_@ -4,6 +4,8 @@ quark \- simple httpd
 .SH SYNOPSIS
 .B quark
 .RB [ \-c ]
+.RB [ \-C
+.IR chrootdir ]
 .RB [ \-d
 .IR cgidir ]
 .RB [ \-e
_AT_@ -29,6 +31,9 @@ Quark is a simple httpd.
 .B \-c
 enable CGI-mode, disabled by default.
 .TP
+.B \-C " chrootdir"
+chroot into chrootdir, by default ".".
+.TP
 .B \-d " cgidir"
 change directory to cgidir for CGI-mode, by default ".".
 .TP
_AT_@ -48,7 +53,7 @@ enable directory listing, disabled by default.
 listen on port, by default "80".
 .TP
 .B \-r " docroot"
-change directory to docroot, by default ".".
+change directory to docroot for static files, by default ".".
 .TP
 .B \-s " server"
 listen on server, by default "127.0.0.1".
diff --git a/quark.c b/quark.c
index d211abb..575eaa0 100644
--- a/quark.c
+++ b/quark.c
_AT_@ -93,7 +93,8 @@ static char location[256];
 static int running = 1;
 static int status;
 static char host[NI_MAXHOST];
-static char reqbuf[MAXBUFLEN];
+static char* reqbuf = NULL;
+static char* reqpath = NULL;
 static char resbuf[MAXBUFLEN];
 static char reqhost[256];
 static char reqmod[256];
_AT_@ -204,7 +205,7 @@ responsefile(void) {
         int r, ffd;
         struct stat st;
 
- if ((r = stat(reqbuf, &st)) == -1 || (ffd = open(reqbuf, O_RDONLY)) == -1) {
+ if ((r = stat(reqpath, &st)) == -1 || (ffd = open(reqpath, O_RDONLY)) == -1) {
                 /* file not found */
                 if (putresentry(HEADER, HttpNotFound, tstamp(0))
                  || putresentry(CONTENTTYPE, texthtml))
_AT_@ -291,8 +292,8 @@ responsedir(void) {
                 return;
         }
         if (len + strlen(docindex) + 1 < MAXBUFLEN)
- memcpy(reqbuf + len, docindex, strlen(docindex) + 1);
- if (access(reqbuf, R_OK) == -1) { /* directory mode */
+ memmove(reqbuf + len, docindex, strlen(docindex) + 1);
+ if (access(reqpath, R_OK) == -1) { /* directory mode */
                 reqbuf[len] = 0; /* cut off docindex again */
                 if(!allowdirlist) {
                         if (putresentry(HEADER, HttpForbidden, tstamp(0))
_AT_@ -303,12 +304,12 @@ responsedir(void) {
                                 writetext("\r\n<html><body>"HttpForbidden"</body></html>\r\n");
                         return;
                 }
- if ((n = scandir(reqbuf, &namelist, NULL, alphasort)) >= 0) {
+ if ((n = scandir(reqpath, &namelist, NULL, alphasort)) >= 0) {
                         responsedirdata(namelist, n);
                         free(namelist);
                 } else {
                         logerrmsg("client %s requests %s but scandir failed: %s\n",
- host, reqbuf, strerror(errno));
+ host, reqpath, strerror(errno));
                 }
         } else {
                 responsefile(); /* docindex */
_AT_@ -406,7 +407,7 @@ response(void) {
                 }
         }
 
- r = stat(reqbuf, &st);
+ r = stat(reqpath, &st);
         if (cgi_mode) {
                 if(r != -1 && !S_ISDIR(st.st_mode))
                         responsefile();
_AT_@ -562,9 +563,9 @@ sighandler(int sig) {
 
 void
 usage(void) {
- fprintf(stderr, "usage: quark [-c] [-d cgidir] [-e cgiscript] [-g group] "
- "[-i index] [-l] [-p port] [-r docroot] [-s server] "
- "[-u user] [-v]\n");
+ fprintf(stderr, "usage: quark [-c] [-C chrootdir] [-d cgidir] "
+ "[-e cgiscript] [-g group] [-i index] [-l] [-p port] "
+ "[-r docroot] [-s server] [-u user] [-v]\n");
         exit(EXIT_FAILURE);
 }
 
_AT_@ -574,12 +575,15 @@ main(int argc, char *argv[]) {
         struct passwd *upwd = NULL;
         struct group *gpwd = NULL;
         struct rlimit rlim;
- int i;
+ int i, docrootlen;
 
         ARGBEGIN {
         case 'c':
                 cgi_mode = 1;
                 break;
+ case 'C':
+ chrootdir = EARGF(usage());
+ break;
         case 'd':
                 cgi_dir = EARGF(usage());
                 break;
_AT_@ -619,6 +623,15 @@ main(int argc, char *argv[]) {
         if (group && *group && !(gpwd = getgrnam(group)))
                 die("error\tinvalid group %s\n", group);
 
+ docrootlen = strlen(docroot);
+ reqpath = malloc(docrootlen + MAXBUFLEN);
+ if (reqpath == NULL) {
+ logerrmsg("error\tcannot allocate memory\n");
+ goto err;
+ }
+ memcpy(reqpath, docroot, docrootlen + 1);
+ reqbuf = reqpath + docrootlen;
+
         signal(SIGCHLD, sighandler);
         signal(SIGHUP, sighandler);
         signal(SIGINT, sighandler);
_AT_@ -666,8 +679,8 @@ main(int argc, char *argv[]) {
                 goto err;
         }
 
- if (chdir(docroot) == -1) {
- logerrmsg("error\tchdir %s: %s\n", docroot, strerror(errno));
+ if (chdir(chrootdir) == -1) {
+ logerrmsg("error\tchdir %s: %s\n", chrootdir, strerror(errno));
                 goto err;
         }
         if (chroot(".") == -1) {
_AT_@ -693,15 +706,17 @@ main(int argc, char *argv[]) {
                 goto err;
         }
 
- logmsg("ready\t%s:%s\t%s\n", servername, serverport, docroot);
+ logmsg("ready\t%s:%s\t%s\n", servername, serverport, chrootdir);
 
         serve(listenfd); /* main loop */
         close(listenfd);
+ free(reqpath);
         freeaddrinfo(ai);
         return EXIT_SUCCESS;
 err:
         if (listenfd != -1)
                 close(listenfd);
+ free(reqpath);
         if (ai)
                 freeaddrinfo(ai);
         return EXIT_FAILURE;
Received on Sun Nov 30 2014 - 23:35:16 CET

This archive was generated by hypermail 2.3.0 : Sun Nov 30 2014 - 23:36:09 CET