source@mandoc.bsd.lv
 help / color / mirror / Atom feed
* mdocml: Let man.cgi run in two modes:   (1) Insecure.
@ 2011-11-24 12:27 kristaps
  0 siblings, 0 replies; only message in thread
From: kristaps @ 2011-11-24 12:27 UTC (permalink / raw)
  To: source

Log Message:
-----------
Let man.cgi run in two modes:

 (1) Insecure.  This means that we're operating over the full file-system
     with access to mandoc(1).  In this mode, mandocdb entries are formatted
     on-the-fly.  The $INSECURE environment variable must be passed to 
     man.cgi for this mode to work.

 (2) Secure.  Manuals are assumed to be pre-formatted in a cache directory,
     which may be set with $CACHE_DIR but default to /cache/man.cgi.  
     This mode works with manup(8), which updates the cached pages from 
     outside of the jail.  man.cgi simply locates the manual file and
     outputs it to stdout.

Modified Files:
--------------
    mdocml:
        cgi.c

Revision Data
-------------
Index: cgi.c
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/cgi.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -Lcgi.c -Lcgi.c -u -p -r1.6 -r1.7
--- cgi.c
+++ cgi.c
@@ -63,6 +63,8 @@ struct	req {
 };
 
 static	int		 atou(const char *, unsigned *);
+static	void		 format_insecure(const char *);
+static	void		 format_secure(const char *);
 static	void		 html_print(const char *);
 static	int 		 kval_decode(char *);
 static	void		 kval_parse(struct kval **, size_t *, char *);
@@ -73,6 +75,7 @@ static	void		 pg_search(const struct man
 				const struct req *, char *);
 static	void		 pg_show(const struct manpaths *,
 				const struct req *, char *);
+static	void		 resp_bad(void);
 static	void		 resp_baddb(void);
 static	void		 resp_badexpr(const struct req *);
 static	void		 resp_badmanual(void);
@@ -83,7 +86,9 @@ static	void		 resp_index(const struct re
 static	void		 resp_search(struct res *, size_t, void *);
 static	void		 resp_searchform(const struct req *);
 
+static	int		  insecure = 1;
 static	const char	 *progname;
+static	const char	 *cache;
 static	const char	 *host;
 
 static	const char * const pages[PAGE__MAX] = {
@@ -361,6 +366,14 @@ resp_badexpr(const struct req *req)
 }
 
 static void
+resp_bad(void)
+{
+	resp_begin_html(500, "Internal Server Error");
+	puts("<P>Generic badness happened.</P>");
+	resp_end_html();
+}
+
+static void
 resp_baddb(void)
 {
 
@@ -421,11 +434,63 @@ pg_index(const struct manpaths *ps, cons
 }
 
 static void
-pg_show(const struct manpaths *ps, const struct req *req, char *path)
+format_insecure(const char *file)
 {
 	pid_t		 pid;
+	char		 cmd[MAXPATHLEN];
+
+	strlcpy(cmd, "man=", MAXPATHLEN);
+	strlcat(cmd, progname, MAXPATHLEN);
+	strlcat(cmd, "/search?expr=%N&sec=%S", MAXPATHLEN);
+
+	/* Get ready to call the child mandoc(1) process. */
+
+	if (-1 == (pid = fork()))
+		exit(EXIT_FAILURE);
+
+	if (pid > 0) {
+		waitpid(pid, NULL, 0);
+		return;
+	}
+
+	dup2(STDOUT_FILENO, STDERR_FILENO);
+
+	puts("Content-Type: text/html; charset=utf-8\n");
+
+	fflush(stdout);
+
+	execlp("mandoc", "mandoc", "-T", 
+		"html", "-O", cmd, file, (char *)NULL);
+}
+
+static void
+format_secure(const char *file)
+{
+	char		 buf[BUFSIZ];
+	int		 fd;
+	ssize_t		 ssz;
+
+	if (-1 == (fd = open(file, O_RDONLY, 0))) {
+		resp_baddb();
+		return;
+	}
+
+	resp_begin_http(200, NULL);
+
+	do {
+		ssz = read(fd, buf, BUFSIZ);
+		if (ssz > 0)
+			write(STDOUT_FILENO, buf, ssz);
+	} while (ssz > 0);
+
+	close(fd);
+}
+
+static void
+pg_show(const struct manpaths *ps, const struct req *req, char *path)
+{
 	char		*sub;
-	char		 file[MAXPATHLEN], cmd[MAXPATHLEN];
+	char		 file[MAXPATHLEN];
 	int		 rc;
 	unsigned int	 vol, rec;
 	DB		*db;
@@ -470,34 +535,17 @@ pg_show(const struct manpaths *ps, const
 
 	/* Extra filename: the first nil-terminated entry. */
 
+	(*db->close)(db);
+
 	strlcpy(file, ps->paths[vol], MAXPATHLEN);
 	strlcat(file, "/", MAXPATHLEN);
 	strlcat(file, (char *)val.data, MAXPATHLEN);
 
-	(*db->close)(db);
-
-	strlcpy(cmd, "man=", MAXPATHLEN);
-	strlcat(cmd, progname, MAXPATHLEN);
-	strlcat(cmd, "/search?expr=%N&sec=%S", MAXPATHLEN);
-
-	/* Get ready to call the child mandoc(1) process. */
-
-	if (-1 == (pid = fork()))
-		exit(EXIT_FAILURE);
-
-	if (pid > 0) {
-		waitpid(pid, NULL, 0);
-		return;
-	}
-
-	dup2(STDOUT_FILENO, STDERR_FILENO);
-
-	puts("Content-Type: text/html; charset=utf-8\n");
-
-	fflush(stdout);
-
-	execlp("mandoc", "mandoc", "-T", 
-		"html", "-O", cmd, file, (char *)NULL);
+	if ( ! insecure) {
+		strlcat(file, ".html", MAXPATHLEN);
+		format_secure(file);
+	} else
+		format_insecure(file);
 }
 
 static void
@@ -586,6 +634,18 @@ main(void)
 	if (NULL == progname)
 		progname = "";
 
+	cache = getenv("CACHE_DIR");
+	if (NULL == cache)
+		cache = "/cache/man.cgi";
+
+	if (NULL == getenv("INSECURE")) {
+		insecure = 0;
+		if (-1 == chdir(cache)) {
+			resp_bad();
+			return(EXIT_FAILURE);
+		}
+	}
+
 	host = getenv("HTTP_HOST");
 	if (NULL == host)
 		host = "localhost";
@@ -629,7 +689,10 @@ main(void)
 	/* Initialise MANPATH. */
 
 	memset(&paths, 0, sizeof(struct manpaths));
-	manpath_parse(&paths, NULL, NULL);
+	if ( ! insecure)
+		manpath_manconf("etc/man.conf", &paths);
+	else
+		manpath_parse(&paths, NULL, NULL);
 
 	/* Route pages. */
 
--
 To unsubscribe send an email to source+unsubscribe@mdocml.bsd.lv

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2011-11-24 12:27 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-11-24 12:27 mdocml: Let man.cgi run in two modes: (1) Insecure kristaps

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).