diff -urN orig/boa-0.94.14rc3/configure.in boa-0.94.14rc3/configure.in --- orig/boa-0.94.14rc3/configure.in 2002-10-26 16:42:43.000000000 +0200 +++ boa-0.94.14rc3/configure.in 2002-10-29 07:30:23.000000000 +0100 @@ -142,6 +142,24 @@ ]) fi +AC_MSG_CHECKING(whether to enable access control support) +AC_ARG_ENABLE(access-control, +[ --enable-access-control Enable support for allow/deny rules], +[ + if test "$enableval" = "yes" ; then + AC_MSG_RESULT(yes) + CFLAGS="$CFLAGS -DACCESS_CONTROL" + ACCESSCONTROL_SOURCE="access.c" + else + AC_MSG_RESULT(no) + fi +], +[ + AC_MSG_RESULT(no) +]) +AC_SUBST(ACCESSCONTROL_SOURCE) + + AC_MSG_CHECKING(whether to compile and link debugging code) AC_ARG_ENABLE(debug, [ --disable-debug Compile and link debugging code], diff -urN orig/boa-0.94.14rc3/docs/boa.texi boa-0.94.14rc3/docs/boa.texi --- orig/boa-0.94.14rc3/docs/boa.texi 2002-10-14 02:21:29.000000000 +0200 +++ boa-0.94.14rc3/docs/boa.texi 2002-10-29 07:30:23.000000000 +0100 @@ -422,6 +422,25 @@ @item ScriptAlias maps a virtual path to a directory for serving scripts. + + @item Allow, Deny + Only supported if Boa is compiled with --enable-access-control. + Allow and Deny allows pattern based access control using shell + wildcards. The string the matching is performed on is the absolute + filesystem filename. The Allow, Deny directives are processed in + order until the first match is found, so to allow files containing + the substring 123 but not the ones containing 1234 you would do: + @itemize @bullet + @item Deny *1234* + @item Allow *123* + @end itemize + + @item Allow + Allows files matching + + @item Deny + Disallowes files matching + @end table @comment node-name, next, previous, up @@ -545,6 +564,8 @@ read. The expectation is that you will configure Boa to run as user "nobody", and only files configured world readable will come out. + If Boa is compiled with --enable-access-control, access control is + supported using the Allow, Deny directives. @item No chroot option diff -urN orig/boa-0.94.14rc3/src/Makefile.in boa-0.94.14rc3/src/Makefile.in --- orig/boa-0.94.14rc3/src/Makefile.in 2002-10-26 16:39:03.000000000 +0200 +++ boa-0.94.14rc3/src/Makefile.in 2002-10-29 07:30:23.000000000 +0100 @@ -30,7 +30,8 @@ SOURCES = alias.c boa.c buffer.c cgi.c cgi_header.c config.c escape.c \ get.c hash.c ip.c log.c mmap_cache.c pipe.c queue.c read.c \ - request.c response.c signals.c util.c sublog.c @ASYNCIO_SOURCE@ + request.c response.c signals.c util.c sublog.c @ASYNCIO_SOURCE@ \ + @ACCESSCONTROL_SOURCE@ OBJS = $(SOURCES:.c=.o) timestamp.o @STRUTIL@ diff -urN orig/boa-0.94.14rc3/src/access.c boa-0.94.14rc3/src/access.c --- orig/boa-0.94.14rc3/src/access.c 1970-01-01 01:00:00.000000000 +0100 +++ boa-0.94.14rc3/src/access.c 2002-10-29 07:31:39.000000000 +0100 @@ -0,0 +1,71 @@ +/* + * Boa, an http server + * Copyright (C) 1999 Larry Doolittle + * + * This program 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 1, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* $Id$ */ + +#include +#include +#include +#include "access.h" + +struct access_node +{ + char *pattern; + char type; +}; + +static int n_access; + +static struct access_node *nodes = NULL; + + +void access_init(void) +{ + n_access = 0; + +} /* access_init */ + + +void access_add(const char *pattern, const int type) +{ + n_access++; + + nodes = realloc(nodes, n_access*sizeof(struct access_node)); + + nodes[n_access - 1].type = type; + nodes[n_access - 1].pattern = strdup(pattern); + +} /* access_add */ + + +int access_allow(const char *file) +{ + int i; + + /* find first match in allow / deny rules */ + for (i=0; i + * + * This program 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 1, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +/* $Id$ */ + +#ifndef _ACCESS_H +#define _ACCESS_H + +#define ACCESS_DENY 0 +#define ACCESS_ALLOW 1 + +void access_init(void); + +void access_add(const char *pattern, const int type); + +int access_allow(const char *file); + +#endif /* _ACCESS_H */ + diff -urN orig/boa-0.94.14rc3/src/config.c boa-0.94.14rc3/src/config.c --- orig/boa-0.94.14rc3/src/config.c 2002-10-26 20:48:22.000000000 +0200 +++ boa-0.94.14rc3/src/config.c 2002-10-29 07:32:37.000000000 +0100 @@ -21,6 +21,7 @@ /* $Id: config.c,v 1.31.2.12 2002/10/26 18:48:22 jnelson Exp $*/ #include "boa.h" +#include "access.h" #include #define DEBUG_CONFIG 0 @@ -75,6 +76,7 @@ static void c_add_mime_types_file(char *v1, char *v2, void *t); static void c_add_mime_type(char *v1, char *v2, void *t); static void c_add_alias(char *v1, char *v2, void *t); +static void c_add_access(char *v1, char *v2, void *t); /* Fakery to keep the value passed to action() a void *, see usage in table and c_add_alias() below */ @@ -140,6 +142,8 @@ {"MaxConnections", S1A, c_set_int, &max_connections}, {"CGIumask", S1A, c_set_int, &cgi_umask}, {"CGILog", S1A, c_set_string, &cgi_log_name}, + {"Allow", S1A, c_add_access, (void*)ACCESS_ALLOW}, + {"Deny", S1A, c_add_access, (void*)ACCESS_DENY}, }; static void c_set_user(char *v1, char *v2, void *t) @@ -324,6 +328,17 @@ add_alias(v1, v2, *(int *) t); } +static void c_add_access(char *v1, char *v2, void *t) +{ +#ifdef ACCESS_CONTROL + access_add(v1, (int)t); +#else + log_error_time(); + fprintf(stderr,"This version of Boa doesn't support access controls.\n" + "Please recompile with --enable-access-control.\n"); +#endif /* ACCESS_CONTROL */ +} + struct ccommand *lookup_keyword(char *c) { struct ccommand *p; @@ -459,6 +474,11 @@ fputs("Could not open boa.conf for reading.\n", stderr); exit(1); } + +#ifdef ACCESS_CONTROL + access_init(); +#endif /* ACCESS_CONTROL */ + parse(config_file); if (!server_name) { diff -urN orig/boa-0.94.14rc3/src/get.c boa-0.94.14rc3/src/get.c --- orig/boa-0.94.14rc3/src/get.c 2002-10-26 20:50:16.000000000 +0200 +++ boa-0.94.14rc3/src/get.c 2002-10-29 07:30:23.000000000 +0100 @@ -23,6 +23,7 @@ /* $Id: get.c,v 1.76.2.10 2002/10/26 18:50:16 jnelson Exp $*/ #include "boa.h" +#include "access.h" /* I think that permanent redirections (301) are supposed * to be absolute URIs, but they can be troublesome. @@ -108,6 +109,13 @@ return 0; } +#ifdef ACCESS_CONTROL + if (!access_allow(req->pathname)) { + send_r_forbidden(req); + return 0; + } +#endif + fstat(data_fd, &statbuf); if (S_ISDIR(statbuf.st_mode)) { /* directory */