=================================================================== RCS file: /cvs/mandoc/cgi.c,v retrieving revision 1.76 retrieving revision 1.79 diff -u -p -r1.76 -r1.79 --- mandoc/cgi.c 2014/07/19 11:35:12 1.76 +++ mandoc/cgi.c 2014/07/21 22:33:01 1.79 @@ -1,4 +1,4 @@ -/* $Id: cgi.c,v 1.76 2014/07/19 11:35:12 schwarze Exp $ */ +/* $Id: cgi.c,v 1.79 2014/07/21 22:33:01 schwarze Exp $ */ /* * Copyright (c) 2011, 2012 Kristaps Dzonsons * Copyright (c) 2014 Ingo Schwarze @@ -71,7 +71,7 @@ static void pg_noresult(const struct req *, const ch static void pg_search(const struct req *); static void pg_searchres(const struct req *, struct manpage *, size_t); -static void pg_show(const struct req *, const char *); +static void pg_show(struct req *, const char *); static void resp_begin_html(int, const char *); static void resp_begin_http(int, const char *); static void resp_end_html(void); @@ -467,6 +467,21 @@ resp_searchform(const struct req *req) } static int +validate_manpath(const struct req *req, const char* manpath) +{ + size_t i; + + if ( ! strcmp(manpath, "mandoc")) + return(1); + + for (i = 0; i < req->psz; i++) + if ( ! strcmp(manpath, req->p[i])) + return(1); + + return(0); +} + +static int validate_filename(const char *file) { @@ -549,8 +564,8 @@ pg_searchres(const struct req *req, struct manpage *r, * without any delay. */ printf("Status: 303 See Other\r\n"); - printf("Location: %s/%s/%s?", - scriptname, req->q.manpath, r[0].file); + printf("Location: http://%s%s/%s/%s?", + HTTP_HOST, scriptname, req->q.manpath, r[0].file); http_printquery(req); printf("\r\n" "Content-Type: text/html; charset=utf-8\r\n" @@ -770,9 +785,10 @@ format(const struct req *req, const char *file) return; } - snprintf(opts, sizeof(opts), - "fragment,man=%s?query=%%N&sec=%%S", - scriptname); + snprintf(opts, sizeof(opts), "fragment,man=%s?" + "manpath=%s&query=%%N&sec=%%S&arch=%s", + scriptname, req->q.manpath, + req->q.arch ? req->q.arch : ""); mparse_result(mp, &mdoc, &man, NULL); if (NULL == man && NULL == mdoc) { @@ -808,7 +824,7 @@ resp_show(const struct req *req, const char *file) } static void -pg_show(const struct req *req, const char *path) +pg_show(struct req *req, const char *path) { char *sub; @@ -819,6 +835,12 @@ pg_show(const struct req *req, const char *path) } *sub++ = '\0'; + if ( ! validate_manpath(req, path)) { + pg_error_badrequest( + "You specified an invalid manpath."); + return; + } + /* * Begin by chdir()ing into the manpath. * This way we can pick up the database files, which are @@ -826,8 +848,9 @@ pg_show(const struct req *req, const char *path) */ if (-1 == chdir(path)) { - pg_error_badrequest( - "You specified an invalid manpath."); + fprintf(stderr, "chdir %s: %s\n", + path, strerror(errno)); + pg_error_internal(); return; } @@ -837,6 +860,9 @@ pg_show(const struct req *req, const char *path) return; } + if (strcmp(path, "mandoc")) + req->q.manpath = path; + resp_begin_html(200, NULL); resp_searchform(req); resp_show(req, sub); @@ -861,8 +887,9 @@ pg_search(const struct req *req) */ if (-1 == (chdir(req->q.manpath))) { - pg_error_badrequest( - "You specified an invalid manpath."); + fprintf(stderr, "chdir %s: %s\n", + req->q.manpath, strerror(errno)); + pg_error_internal(); return; } @@ -953,6 +980,12 @@ main(void) if (NULL != (querystring = getenv("QUERY_STRING"))) http_parse(&req, querystring); + + if ( ! validate_manpath(&req, req.q.manpath)) { + pg_error_badrequest( + "You specified an invalid manpath."); + return(EXIT_FAILURE); + } /* Dispatch to the three different pages. */