* Usage: as CGI script
*/
/*
- * Copyright (C) 1998-1999,2003 Ian Jackson
+ * Copyright 1996-2013,2016 Ian Jackson <ijackson@chiark.greenend.org.uk>
+ * Copyright 1998 David Damerell <damerell@chiark.greenend.org.uk>
+ * Copyright 1999,2003
+ * Chancellor Masters and Scholars of the University of Cambridge
+ * Copyright 2010 Tony Finch <fanf@dotat.at>
+ * Copyright 2013,2016 Mark Wooding <mdw@distorted.org.uk>
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
+ * the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with userv-utils; if not, write to the Free Software
- * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * $Id$
+ * along with userv-utils; if not, see http://www.gnu.org/licenses/.
*/
#include <stdio.h>
#include "ucgi.h"
+static const char *const default_envok[] = {
+ "AUTH_TYPE",
+ "CONTENT_TYPE",
+ "CONTENT_LENGTH",
+ "DOCUMENT_ROOT",
+ "GATEWAY_INTERFACE",
+ "HTTP_*",
+ "HTTPS",
+ "PATH_INFO",
+ "PATH_TRANSLATED",
+ "QUERY_STRING",
+ "REDIRECT_*",
+ "REMOTE_*",
+ "REQUEST_METHOD",
+ "REQUEST_URI",
+ "SCRIPT_*",
+ "SERVER_*",
+ "SSL_*",
+ 0
+};
+
struct buildargs {
const char **v;
int n, max;
};
static void addarg(struct buildargs *args, const char *a) {
- if (args->n > args->max) error("too many arguments");
+ if (args->n > args->max) error("too many arguments", 500);
args->v[args->n++]= a;
}
size_t l;
char *a;
- l= strlen(ev); if (l > MAX_ENVVAR_VALUE) error("environment variable too long");
+ l= strlen(ev);
+ if (l > MAX_ENVVAR_VALUE) error("environment variable too long", 500);
a= xmalloc(strlen(en)+l+6);
sprintf(a,"-DE_%s=%s",en,ev);
addarg(args, a);
int main(int argc, const char **argv) {
char *username;
- const char *slash2, *pathi, *av;
+ const char *slash2, *pathi, *ev, *av;
+ const char *const *envok = 0;
size_t usernamelen, l;
struct buildargs args;
pid_t child, rchild;
D( printf(";;; UCGI\n"); )
}
- if (argc > MAX_ARGS) error("too many arguments");
+ if (argc > MAX_ARGS) error("too many arguments", 500);
+
+ ev= getenv("UCGI_ENV_FILTER");
+ if (ev)
+ envok= load_filters(LOADF_MUST, ev, LF_END);
+ else
+ envok= load_filters(0, "/etc/userv/ucgi.env-filter", LF_END);
pathi= getenv("PATH_INFO");
- if (!pathi) error("PATH_INFO not found");
+ if (!pathi) error("PATH_INFO not found", 500);
D( if (debugmode) {
printf(";; find user name...\n"
";; initial PATH_INFO = `%s'\n",
pathi);
} )
- if (pathi[0] != '/' || pathi[1] != '~') error("PATH_INFO must start with /~");
- slash2= strchr(pathi+2,'/'); if (!slash2) error("PATH_INFO must have more than one /");
+ if (pathi[0] != '/' || pathi[1] != '~')
+ error("PATH_INFO must start with /~", 400);
+ slash2= strchr(pathi+2,'/');
+ if (!slash2) error("PATH_INFO must have more than one /", 400);
usernamelen= slash2-(pathi+2);
- if (usernamelen > MAX_USERNAME_LEN) error("PATH_INFO username too long");
+ if (usernamelen > MAX_USERNAME_LEN) error("PATH_INFO username too long", 400);
username= xmalloc(usernamelen+1);
memcpy(username,pathi+2,usernamelen); username[usernamelen]= 0;
D( if (debugmode)
printf(";; user = `%s'; tail = `%s'\n", username, slash2); )
- if (!isalpha(username[0])) error("username 1st character is not alphabetic");
+ if (!isalpha(username[0]))
+ error("username 1st character is not alphabetic", 400);
xsetenv("PATH_INFO",slash2,1);
args.n= 0; args.max= argc + MAX_ENVVARS + 10;
addarg(&args, "userv");
if (debugmode) addarg(&args, "-DDEBUG=1");
- filter_environment(FILTF_WILDCARD, "", envok, add_userv_var, &args);
+ filter_environment(FILTF_WILDCARD, "", envok, default_envok,
+ add_userv_var, &args);
addarg(&args, username);
addarg(&args, "www-cgi");