| Author: Robin H. Johnson <robbat2@gentoo.org> |
| Date: 2006-08-09 |
| |
| This patch allows a CVS server to deny usage of specific commands, based on |
| input in the environment. |
| |
| Just set the CVS_BLOCK_REQUESTS env var with all of the commands you want, |
| seperated by spaces. Eg: |
| CVS_BLOCK_REQUESTS="Gzip-stream gzip-file-contents" |
| would block ALL usage of compression. |
| |
| Please see the array 'struct request requests[]' in src/server.c for a full |
| list of commands. |
| |
| Please note that if you block any commands marked as RQ_ESSENTIAL, CVS clients |
| may fail! (This includes 'ci'!). |
| |
| See the companion cvs-custom.c for a wrapper that can enforce the environment variable for pserver setups. |
| |
| Signed-off-by: Robin H. Johnson <robbat2@gentoo.org> |
| |
| diff -Nuar --exclude '*~' -U 10 cvs-1.12.12.orig/src/server.c cvs-1.12.12/src/server.c |
| --- cvs-1.12.12.orig/src/server.c 2005-04-14 14:13:29.000000000 +0000 |
| +++ cvs-1.12.12/src/server.c 2006-08-09 01:40:44.000000000 +0000 |
| @@ -5836,43 +5836,90 @@ |
| #undef REQ_LINE |
| }; |
| #endif /* SERVER_SUPPORT or CLIENT_SUPPORT */ |
| |
| |
| |
| #ifdef SERVER_SUPPORT |
| /* |
| * This server request is not ignored by the secondary. |
| */ |
| + |
| +/* Hack by Robin H. Johnson <robbat2@gentoo.org>. |
| + * Allow the server ENV to specify what request types are to be ignored. |
| + */ |
| + |
| +static char blocked_requests[BUFSIZ] = " "; |
| + |
| +static void build_blocked_requests() { |
| + char *tmp = getenv("CVS_BLOCK_REQUESTS"); |
| + |
| + if (tmp != NULL && strlen(tmp) > 0) { |
| + // move to our custom buffer |
| + strncat(blocked_requests, tmp, sizeof(blocked_requests)-strlen(blocked_requests)); |
| + //add a space on the end as well for searching |
| + strncat(blocked_requests, " ", sizeof(blocked_requests)-strlen(blocked_requests)); |
| + } |
| + |
| + // now blocked_requests contains the list of every request that we do not |
| + // want to serve |
| +} |
| + |
| +// returns 0 if we should serve this request |
| +// use as if(checker(FOO)) continue; |
| +static int serve_valid_requests_checker(char *reqname) { |
| + char needle[BUFSIZ] = " "; |
| + char *tmp; |
| + |
| + if(!blocked_requests || strlen(blocked_requests) < 2) |
| + return 0; |
| + |
| + // we want to look for ' 'reqname' ' |
| + snprintf(needle, sizeof(needle), " %s ", reqname); |
| + |
| + // now do the search |
| + tmp = strstr(blocked_requests, needle); |
| + |
| + if (tmp != NULL) |
| + return 1; |
| + |
| + return 0; |
| + |
| +} |
| + |
| static void |
| serve_valid_requests (char *arg) |
| { |
| struct request *rq; |
| |
| /* Since this is processed in the first pass, don't reprocess it in the |
| * second. |
| * |
| * We still print errors since new errors could have been generated in the |
| * second pass. |
| */ |
| if (print_pending_error () |
| #ifdef PROXY_SUPPORT |
| || reprocessing |
| #endif /* PROXY_SUPPORT */ |
| ) |
| return; |
| + |
| + build_blocked_requests(); |
| |
| buf_output0 (buf_to_net, "Valid-requests"); |
| for (rq = requests; rq->name != NULL; rq++) |
| { |
| if (rq->func != NULL) |
| { |
| + if(serve_valid_requests_checker(rq->name)) |
| + continue; |
| buf_append_char (buf_to_net, ' '); |
| buf_output0 (buf_to_net, rq->name); |
| } |
| } |
| buf_output0 (buf_to_net, "\nok\n"); |
| |
| /* The client is waiting for the list of valid requests, so we |
| must send the output now. */ |
| buf_flush (buf_to_net, 1); |
| } |
| @@ -6353,20 +6400,24 @@ |
| cmd += len; |
| else if (cmd[len] == ' ') |
| cmd += len + 1; |
| else |
| /* |
| * The first len characters match, but it's a different |
| * command. e.g. the command is "cooperate" but we matched |
| * "co". |
| */ |
| continue; |
| + // Ignore commands that we are supposed to ignore. |
| + if(serve_valid_requests_checker(rq->name)) |
| + continue; |
| + |
| |
| if (!(rq->flags & RQ_ROOTLESS) |
| && current_parsed_root == NULL) |
| { |
| /* For commands which change the way in which data |
| is sent and received, for example Gzip-stream, |
| this does the wrong thing. Since the client |
| assumes that everything is being compressed, |
| unconditionally, there is no way to give this |
| error to the client without turning on |