Index: ChangeLog =================================================================== RCS file: /cvsroot/cvs/ccvs/ChangeLog,v retrieving revision 1.1348 diff -u -r1.1348 ChangeLog --- ChangeLog 8 May 2007 12:35:53 -0000 1.1348 +++ ChangeLog 8 May 2007 21:04:30 -0000 @@ -1,3 +1,22 @@ +2007-05-08 Sylvain Beucler + + * Adapted 2001/2004 patch from Roland Mas : + + * main.c (main): Use new root_allow_regexp_add function, declare + new --allow-root-regexp option parameter. + + * root.c: Added new functions root_allow_regexp_add and + root_allow_compare_regexp, new variables + root_allow_regexp. Modified root_allow_ok, root_allow_used and + root_allow_free. The code adds the matched repository path to + root_allow as if specified using --allow-root. --allow-root is not + mandatory anymore if --allow-root-regexp is used instead. + + * NEWS, cvs.texinfo: Documented these changes. + + * sanity.sh: added test cases as pserver-3b and pserver-3c, + updated pserver-3 + 2007-05-07 Derek Price * NEWS: Note removal of remote `cvs init'. Index: NEWS =================================================================== RCS file: /cvsroot/cvs/ccvs/NEWS,v retrieving revision 1.367 diff -u -r1.367 NEWS --- NEWS 8 May 2007 12:35:53 -0000 1.367 +++ NEWS 8 May 2007 21:04:31 -0000 @@ -23,6 +23,11 @@ * When UseNewInfoFmtStrings is enabled, the %{vV} formats will now expose the real version instead of NONE for removed files. +* A new command line option, --allow-root-regexp, was added. It +allows to specify a list of regular expressions for the repositories +locations, in addition to the list of exact paths. + + BUG FIXES * The CVS server will no longer allow clients to run `cvs init'. Index: doc/cvs.texinfo =================================================================== RCS file: /cvsroot/cvs/ccvs/doc/cvs.texinfo,v retrieving revision 1.698 diff -u -r1.698 cvs.texinfo --- doc/cvs.texinfo 12 Sep 2006 20:30:25 -0000 1.698 +++ doc/cvs.texinfo 8 May 2007 21:04:38 -0000 @@ -2606,6 +2606,10 @@ different @sc{cvsroot} directory will not be allowed to connect. If there is more than one @sc{cvsroot} directory which you want to allow, repeat the option. +If there is a whole class of @sc{cvsroot} +directories which you want to allow, you can also specify a +regular expression with the @samp{--allow-root-regexp} +option. This option is repeatable, too. (Unfortunately, many versions of @code{inetd} have very small limits on the number of arguments and/or the total length of the command. The usual solution to this problem is @@ -12336,6 +12340,12 @@ in @sc{cvs} 1.9 and older). See @ref{Password authentication server}. +@item --allow-root-regexp=@var{rootdir} +Specify a regular expression to be matched by legal +@sc{cvsroot} directories (server only) (not in @sc{cvs} +1.12.13 and earlier). See @ref{Password authentication +server}. + @item -a Authenticate all communication (client only) (not in @sc{cvs} 1.9 and older). See @ref{Global options}. @@ -15944,6 +15954,7 @@ specific reason for denying authorization. Check that the username and password specified are correct and that the @code{CVSROOT} specified is allowed by @samp{--allow-root} +or @samp{--allow-root-regexp} in @file{inetd.conf}. See @ref{Password authenticated}. @item cvs @var{command}: Bad root @var{directory} Index: src/main.c =================================================================== RCS file: /cvsroot/cvs/ccvs/src/main.c,v retrieving revision 1.268 diff -u -r1.268 main.c --- src/main.c 17 May 2006 15:24:30 -0000 1.268 +++ src/main.c 8 May 2007 21:04:38 -0000 @@ -576,6 +576,7 @@ {"verify-arg", required_argument, NULL, 12}, #ifdef SERVER_SUPPORT {"allow-root", required_argument, NULL, 3}, + {"allow-root-regexp", required_argument, NULL, 14}, {"timeout", required_argument, NULL, 13}, #endif /* SERVER_SUPPORT */ {0, 0, 0, 0} @@ -823,6 +824,10 @@ /* --allow-root */ root_allow_add (optarg, gConfigPath); break; + case 14: + /* --allow-root-regexp */ + root_allow_regexp_add (optarg, gConfigPath); + break; case 13: /* --timeout */ connection_timeout = strtol (optarg, &end, 10); Index: src/root.c =================================================================== RCS file: /cvsroot/cvs/ccvs/src/root.c,v retrieving revision 1.125 diff -u -r1.125 root.c --- src/root.c 24 Apr 2006 18:50:27 -0000 1.125 +++ src/root.c 8 May 2007 21:04:38 -0000 @@ -285,6 +285,7 @@ directories. Then we can check against them when a remote user hands us a CVSROOT directory. */ static List *root_allow; +static List *root_allow_regexp; static void delconfig (Node *n) @@ -308,21 +309,65 @@ } void +root_allow_regexp_add (const char *arg, const char *configPath) +{ + Node *n; + + if (!root_allow_regexp) root_allow_regexp = getlist(); + n = getnode(); + n->key = xstrdup (arg); + + /* This is a regexp, not the final cvsroot path - we cannot attach + it a config. So we attach configPath and we'll root_allow_add() + the actual, matching root in root_allow_compare_regexp() */ + n->data = (void*)configPath; + + addnode (root_allow_regexp, n); +} + +void root_allow_free (void) { dellist (&root_allow); + dellist (&root_allow_regexp); } bool root_allow_used (void) { - return root_allow != NULL; + return (root_allow != NULL) || (root_allow_regexp != NULL); +} + +/* walklist() callback for determining if 'root_to_check' matches + n->key (a regexp). If yes, 'root_to_check' will be added as if + directly specified through --allow-root. + */ +static int +root_allow_compare_regexp (Node *n, void *root_to_check) +{ + int status; + regex_t re; + + if (regcomp(&re, n->key, + REG_EXTENDED|REG_NOSUB) != 0) + { + return 0; /* report error? */ + } + status = regexec(&re, root_to_check, (size_t) 0, NULL, 0); + regfree(&re); + if (status == 0) + { + /* n->data contains gConfigPath */ + root_allow_add (root_to_check, n->data); + return 1; + } + return 0; } bool root_allow_ok (const char *arg) { - if (!root_allow) + if (!root_allow && !root_allow_regexp) { /* Probably someone upgraded from CVS before 1.9.10 to 1.9.10 or later without reading the documentation about @@ -334,12 +379,18 @@ back "error" rather than waiting for the next request which expects responses. */ printf ("\ -error 0 Server configuration missing --allow-root in inetd.conf\n"); +error 0 Server configuration missing --allow-root or --allow-root-regexp in inetd.conf\n"); exit (EXIT_FAILURE); } + /* Look for 'arg' in the list of full-path allowed roots */ if (findnode (root_allow, arg)) return true; + + /* Match 'arg' against the list of allowed roots regexps */ + if (walklist (root_allow_regexp, root_allow_compare_regexp, (void*)arg)) + return true; + return false; } Index: src/root.h =================================================================== RCS file: /cvsroot/cvs/ccvs/src/root.h,v retrieving revision 1.24 diff -u -r1.24 root.h --- src/root.h 24 Apr 2006 18:50:27 -0000 1.24 +++ src/root.h 8 May 2007 21:04:38 -0000 @@ -89,6 +89,7 @@ __attribute__ ((__malloc__)); void Create_Root (const char *dir, const char *rootdir); void root_allow_add (const char *, const char *configPath); +void root_allow_regexp_add (const char *, const char *configPath); void root_allow_free (void); bool root_allow_used (void); bool root_allow_ok (const char *); Index: src/sanity.sh =================================================================== RCS file: /cvsroot/cvs/ccvs/src/sanity.sh,v retrieving revision 1.1175 diff -u -r1.1175 sanity.sh --- src/sanity.sh 8 May 2007 12:35:53 -0000 1.1175 +++ src/sanity.sh 8 May 2007 21:04:51 -0000 @@ -31622,7 +31622,7 @@ willfail: :whocares EOF dotest_fail pserver-3 "$servercvs pserver" \ -"error 0 Server configuration missing --allow-root in inetd.conf" <