bug-cvs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: 2 security concerns: remote init, and disabling CVSROOT/passwd


From: Derek Price
Subject: Re: 2 security concerns: remote init, and disabling CVSROOT/passwd
Date: Wed, 09 May 2007 19:58:41 -0400
User-agent: Thunderbird 1.5.0.10 (Windows/20070221)

I've committed this with a few minor changes.  Thanks Sylvain!

Derek
--
Derek R. Price
CVS Solutions Architect
Get CVS support at Ximbiot <http://ximbiot.com>!
v: +1 248.835.1260
f: +1 248.835.1263
<mailto:derek@ximbiot.com>


Sylvain Beucler wrote:
I don't know if you still want the --allow-root-regexp patch merged into 1.12.x, but I found some discussion in the archives and it sounds like we were waiting on documentation and test cases for the change.

I think this is a good way to prevent access to repositories outside
or downside the allowed hierarchy, while keeping it maintainable (no
list of repositories to rebuild), e.g.
--allow-root-regexp='^/srv/cvs/sources/[^/]+'

Unless there's a better way, here's an updated patch against HEAD :)



------------------------------------------------------------------------

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  <beuc@beuc.net>
+
+       * Adapted 2001/2004 patch from Roland Mas <lolando@debian.org>:
+
+       * 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  <derek@ximbiot.com>
* 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" <<EOF
+"error 0 Server configuration missing --allow-root or --allow-root-regexp in 
inetd.conf" <<EOF
 BEGIN AUTH REQUEST
 $CVSROOT_DIRNAME
 testme
@@ -31640,6 +31640,27 @@
 END AUTH REQUEST
 EOF
+ regexp='^'`dirname ${CVSROOT_DIRNAME}`'/[^/]+$'
+           dotest pserver-3b "${testcvs} --allow-root-regexp=$regexp pserver" \
+"I LOVE YOU" <<EOF
+BEGIN AUTH REQUEST
+${CVSROOT_DIRNAME}
+testme
+Ay::'d
+END AUTH REQUEST
+EOF
+
+            regexp='^'`dirname ${CVSROOT_DIRNAME}`'/[^/]+$'
+           dotest_fail pserver-3c "${testcvs} --allow-root-regexp=$regexp 
pserver" \
+"$CPROG pserver: ${CVSROOT_DIRNAME}/subdir: no such repository
+I HATE YOU" <<EOF
+BEGIN AUTH REQUEST
+${CVSROOT_DIRNAME}/subdir
+testme
+Ay::'d
+END AUTH REQUEST
+EOF
+
            # Confirm that not sending a newline during auth cannot constitute
            # a denial-of-service attack.  This assumes that PATH_MAX is less
            # than 65536 bytes.  If PATH_MAX is larger than 65535 bytes, this




reply via email to

[Prev in Thread] Current Thread [Next in Thread]