|
Lines 1-5
Link Here
|
| 1 |
--- ./fcgiwrap.c.orig 2010-06-03 16:18:21.000000000 +0200 |
1 |
--- fcgiwrap.c.orig 2014-09-22 12:36:32.000000000 +0200 |
| 2 |
+++ ./fcgiwrap.c 2010-06-15 14:54:38.232029168 +0200 |
2 |
+++ fcgiwrap.c 2014-09-22 12:41:59.000000000 +0200 |
| 3 |
@@ -43,6 +43,7 @@ |
3 |
@@ -43,6 +43,7 @@ |
| 4 |
#include <ctype.h> |
4 |
#include <ctype.h> |
| 5 |
|
5 |
|
|
Lines 7-10
Link Here
|
| 7 |
+#include <netinet/in.h> |
7 |
+#include <netinet/in.h> |
| 8 |
#include <sys/socket.h> |
8 |
#include <sys/socket.h> |
| 9 |
#include <sys/un.h> |
9 |
#include <sys/un.h> |
|
|
10 |
#include <netinet/in.h> |
| 11 |
@@ -58,6 +59,8 @@ |
| 10 |
|
12 |
|
|
|
13 |
extern char **environ; |
| 14 |
static char * const * inherited_environ; |
| 15 |
+static const char **allowed_programs; |
| 16 |
+static size_t allowed_programs_count; |
| 17 |
|
| 18 |
static const char * blacklisted_env_vars[] = { |
| 19 |
"AUTH_TYPE", |
| 20 |
@@ -485,6 +488,19 @@ |
| 21 |
} |
| 22 |
} |
| 23 |
|
| 24 |
+static bool is_allowed_program(const char *program) { |
| 25 |
+ size_t i; |
| 26 |
+ if (!allowed_programs_count) |
| 27 |
+ return true; |
| 28 |
+ |
| 29 |
+ for (i = 0; i < allowed_programs_count; i++) { |
| 30 |
+ if (!strcmp(allowed_programs[i], program)) |
| 31 |
+ return true; |
| 32 |
+ } |
| 33 |
+ |
| 34 |
+ return false; |
| 35 |
+} |
| 36 |
+ |
| 37 |
static void cgi_error(const char *message, const char *reason, const char *filename) |
| 38 |
{ |
| 39 |
printf("Status: %s\r\nContent-Type: text/plain\r\n\r\n%s\r\n", |
| 40 |
@@ -541,6 +557,9 @@ |
| 41 |
if (!filename) |
| 42 |
cgi_error("403 Forbidden", "Cannot get script name, are DOCUMENT_ROOT and SCRIPT_NAME (or SCRIPT_FILENAME) set and is the script executable?", NULL); |
| 43 |
|
| 44 |
+ if (!is_allowed_program(filename)) |
| 45 |
+ cgi_error("403 Forbidden", "The given script is not allowed to execute", filename); |
| 46 |
+ |
| 47 |
last_slash = strrchr(filename, '/'); |
| 48 |
if (!last_slash) |
| 49 |
cgi_error("403 Forbidden", "Script name must be a fully qualified path", filename); |
| 50 |
@@ -760,7 +779,7 @@ |
| 51 |
char *socket_url = NULL; |
| 52 |
int c; |
| 53 |
|
| 54 |
- while ((c = getopt(argc, argv, "c:hfs:")) != -1) { |
| 55 |
+ while ((c = getopt(argc, argv, "c:hfs:p:")) != -1) { |
| 56 |
switch (c) { |
| 57 |
case 'f': |
| 58 |
stderr_to_fastcgi++; |
| 59 |
@@ -773,6 +792,7 @@ |
| 60 |
" -c <number>\t\tNumber of processes to prefork\n" |
| 61 |
" -s <socket_url>\tSocket to bind to (say -s help for help)\n" |
| 62 |
" -h\t\t\tShow this help message and exit\n" |
| 63 |
+ " -p <path>\t\tRestrict execution to this script. (repeated options will be merged)\n" |
| 64 |
"\nReport bugs to Grzegorz Nosek <"PACKAGE_BUGREPORT">.\n" |
| 65 |
PACKAGE_NAME" home page: <http://nginx.localdomain.pl/wiki/FcgiWrap>\n", |
| 66 |
argv[0] |
| 67 |
@@ -784,8 +804,14 @@ |
| 68 |
case 's': |
| 69 |
socket_url = strdup(optarg); |
| 70 |
break; |
| 71 |
+ case 'p': |
| 72 |
+ allowed_programs = realloc(allowed_programs, (allowed_programs_count + 1) * sizeof (char *)); |
| 73 |
+ if (!allowed_programs) |
| 74 |
+ abort(); |
| 75 |
+ allowed_programs[allowed_programs_count++] = strdup(optarg); |
| 76 |
+ break; |
| 77 |
case '?': |
| 78 |
- if (optopt == 'c' || optopt == 's') |
| 79 |
+ if (optopt == 'c' || optopt == 's' || optopt == 'p') |
| 80 |
fprintf(stderr, "Option -%c requires an argument.\n", optopt); |
| 81 |
else if (isprint(optopt)) |
| 82 |
fprintf(stderr, "Unknown option `-%c'.\n", optopt); |