From d743a7f8d160d6e2eeefc559e9e5a783199f9859 Mon Sep 17 00:00:00 2001 From: Ingo Schwarze Date: Fri, 18 Mar 2016 13:22:27 +0000 Subject: Make the SCRIPT_NAME logic simpler, safer, and make it actually work; in part based on ideas by bentley@. While here, improve the documentation. --- cgi.c | 40 +++++++++++--------------- cgi.h.example | 3 +- man.cgi.8 | 91 ++++++++++++++++++++++++++++++++--------------------------- 3 files changed, 68 insertions(+), 66 deletions(-) diff --git a/cgi.c b/cgi.c index ddb318d6..ffef5031 100644 --- a/cgi.c +++ b/cgi.c @@ -1,4 +1,4 @@ -/* $Id: cgi.c,v 1.118 2016/03/17 22:06:44 schwarze Exp $ */ +/* $Id: cgi.c,v 1.119 2016/03/18 13:22:27 schwarze Exp $ */ /* * Copyright (c) 2011, 2012 Kristaps Dzonsons * Copyright (c) 2014, 2015, 2016 Ingo Schwarze @@ -84,7 +84,7 @@ static int validate_filename(const char *); static int validate_manpath(const struct req *, const char *); static int validate_urifrag(const char *); -static const char *scriptname; /* CGI script name */ +static const char *scriptname = SCRIPT_NAME; static const int sec_prios[] = {1, 4, 5, 8, 6, 3, 7, 2, 9}; static const char *const sec_numbers[] = { @@ -370,7 +370,7 @@ resp_searchform(const struct req *req) puts(""); printf("
\n" - "
\n" + "\n" "
\n" "Manual Page Search Parameters\n", scriptname); @@ -507,12 +507,13 @@ pg_index(const struct req *req) resp_searchform(req); printf("

\n" "This web interface is documented in the\n" - "man.cgi\n" + "man.cgi\n" "manual, and the\n" - "apropos\n" + "apropos\n" "manual explains the query syntax.\n" "

\n", - scriptname, scriptname); + scriptname, *scriptname == '\0' ? "" : "/", + scriptname, *scriptname == '\0' ? "" : "/"); resp_end_html(); } @@ -536,7 +537,7 @@ pg_error_badrequest(const char *msg) "

\n"); puts(msg); printf("Try again from the\n" - "main page.\n" + "main page.\n" "

", scriptname); resp_end_html(); } @@ -573,8 +574,10 @@ pg_searchres(const struct req *req, struct manpage *r, size_t sz) * without any delay. */ printf("Status: 303 See Other\r\n"); - printf("Location: http://%s%s/%s/%s", - HTTP_HOST, scriptname, req->q.manpath, r[0].file); + printf("Location: http://%s/%s%s%s/%s", + HTTP_HOST, scriptname, + *scriptname == '\0' ? "" : "/", + req->q.manpath, r[0].file); printf("\r\n" "Content-Type: text/html; charset=utf-8\r\n" "\r\n"); @@ -589,8 +592,9 @@ pg_searchres(const struct req *req, struct manpage *r, size_t sz) for (i = 0; i < sz; i++) { printf("\n" "\n" - "q.manpath, r[i].file); + "q.manpath, r[i].file); printf("\">"); html_print(r[i].names); printf("\n" @@ -808,7 +812,7 @@ format(const struct req *req, const char *file) memset(&conf, 0, sizeof(conf)); conf.fragment = 1; usepath = strcmp(req->q.manpath, req->p[0]); - mandoc_asprintf(&conf.man, "%s?query=%%N&sec=%%S%s%s%s%s", + mandoc_asprintf(&conf.man, "/%s?query=%%N&sec=%%S%s%s%s%s", scriptname, req->q.arch ? "&arch=" : "", req->q.arch ? req->q.arch : "", @@ -1006,18 +1010,6 @@ main(void) return EXIT_FAILURE; } - /* Scan our run-time environment. */ - - if (NULL == (scriptname = getenv("SCRIPT_NAME"))) - scriptname = ""; - - if ( ! validate_urifrag(scriptname)) { - fprintf(stderr, "unsafe SCRIPT_NAME \"%s\"\n", - scriptname); - pg_error_internal(); - return EXIT_FAILURE; - } - /* * First we change directory into the MAN_DIR so that * subsequent scanning for manpath directories is rooted diff --git a/cgi.h.example b/cgi.h.example index c4878d34..7e5f3917 100644 --- a/cgi.h.example +++ b/cgi.h.example @@ -1,7 +1,8 @@ /* Example compile-time configuration file for man.cgi(8). */ #define HTTP_HOST "mdocml.bsd.lv" -#define MAN_DIR "/var/www/man" +#define SCRIPT_NAME "cgi-bin/man.cgi" +#define MAN_DIR "/man" #define CSS_DIR "" #define CUSTOMIZE_TITLE "Manual pages with mandoc" #define COMPAT_OLDURI Yes diff --git a/man.cgi.8 b/man.cgi.8 index e60649b4..c27fb65d 100644 --- a/man.cgi.8 +++ b/man.cgi.8 @@ -1,4 +1,4 @@ -.\" $Id: man.cgi.8,v 1.14 2016/03/18 01:22:56 schwarze Exp $ +.\" $Id: man.cgi.8,v 1.15 2016/03/18 13:22:27 schwarze Exp $ .\" .\" Copyright (c) 2014, 2015, 2016 Ingo Schwarze .\" @@ -183,31 +183,42 @@ Only useful for running on www.openbsd.org to deal with old URIs containing .Qq "manpath=OpenBSD " where the blank character has to be translated to a hyphen. When compiling for other sites, this definition can be deleted. -.It Ev CSS_DIR -An optional path to the directory containing the CSS files, +.It Dv CSS_DIR +An optional file system path to the directory containing the file +.Pa mandoc.css , to be specified relative to the server's document root, and to be specified without a trailing slash. -When not specified, the CSS files -are assumed to be in the document root. +When empty, the CSS file is assumed to be in the document root. +Otherwise, a leading slash is needed. This is used in generated HTML code. -.It Ev CUSTOMIZE_TITLE +.It Dv CUSTOMIZE_TITLE An ASCII string to be used for the HTML element. -.It Ev HTTP_HOST +.It Dv HTTP_HOST The FQDN of the (possibly virtual) host the HTTP server is running on. This is used for .Ic Location: headers in HTTP 303 responses. -.It Ev MAN_DIR -A path to the +.It Dv MAN_DIR +A file system path to the .Nm -data directory to be used instead of -.Pa /var/www/man , -relative to the web server +data directory relative to the web server .Xr chroot 2 -directory, to be specified without a trailing slash. -This is prepended to the manpath when opening +directory, to be specified with a leading slash and without a trailing slash. +It needs to have at least one component; the root directory cannot be used +for this purpose. +The files +.Pa manpath.conf , +.Pa header.html , +and +.Pa footer.html +are looked up in this directory. +It is also prepended to the manpath when opening .Xr mandoc.db 5 and manual page files. +.It Dv SCRIPT_NAME +The initial component of URIs, to be specified without leading +and trailing slashes. +It can be empty. .El .Pp After editing @@ -234,14 +245,11 @@ The .Cm http:// protocol specifier. .It -The host name and a following slash. +The host name. .It -The path to the program, normally -.Pa cgi-bin/man.cgi/ . -On -.Lk http://man.openbsd.org/ , -.Xr httpd 8 -is configured such that the path to the program can be omitted. +The +.Dv SCRIPT_NAME , +preceded by a slash unless empty. .It To show a single page, a slash, the manpath, another slash, and the name of the requested file, for example @@ -304,13 +312,20 @@ the underscore .Pq Sq _ .El .Pp -In particular, this applies to the -.Ev SCRIPT_NAME , -to all manpaths, and to all architecture names. +In particular, this applies to all manpaths and architecture names. .Sh ENVIRONMENT The web server may pass the following CGI variables to .Nm : .Bl -tag -width Ds +.It Ev SCRIPT_NAME +The initial part of the the URI passed from the client to the server, +starting after the server's host name and ending before +.Ev PATH_INFO . +This is ignored by +.Nm . +When constructing URIs for links and redirections, the +.Dv SCRIPT_NAME +preprocessor constant is used instead. .It Ev PATH_INFO The final part of the URI path passed from the client to the server, starting after the @@ -326,17 +341,6 @@ It is the final part of the URI, after the question mark. It is used by the .Cm search page to acquire the named parameters it needs. -.It Ev SCRIPT_NAME -The path to the -.Nm -binary relative to the server root, usually -.Pa /cgi-bin/man.cgi . -This is used for generating URIs to be embedded -in generated HTML code and HTTP headers. -If this contains any character not contained in the -.Sx Restricted character set , -.Nm -reports an internal server error and exits without doing anything. .El .Sh FILES .Bl -tag -width Ds @@ -346,13 +350,18 @@ Default web server directory. All the following paths are specified relative to this directory. .It Pa /cgi-bin/man.cgi -The path to the +The usual file system path to the .Nm -program relative to the server root. -Can be overridden by -.Ev SCRIPT_NAME . +program inside the web server +.Xr chroot 2 +directory. +A different name can be chosen, but in any case, it needs to be configured in +.Xr httpd.conf 5 . .It Pa /htdocs -The path to the server document root relative to the server root. +The file system path to the server document root directory +relative to the server +.Xr chroot 2 +directory. This is part of the web server configuration and not specific to .Nm . .It Pa /htdocs/mandoc.css @@ -364,7 +373,7 @@ Default .Nm data directory containing all the manual trees. Can be overridden by -.Ev MAN_DIR . +.Dv MAN_DIR . .It Pa /man/mandoc/man1/apropos.1 , /man/mandoc/man8/man.cgi.8 Manual pages documenting .Nm -- cgit v1.2.3-56-ge451