[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

[PATCH] ra_svn cyrus auth should prefer EXTERNAL over ANONYMOUS

From: David Glasser <glasser_at_davidglasser.net>
Date: Thu, 23 Oct 2008 10:09:36 -0700

In ra_svn's internal auth, we explicitly prefer EXTERNAL over
ANONYMOUS over everything else:

  if (sess->is_tunneled && find_mech(mechlist, "EXTERNAL"))
        /* Ask the server to use the tunnel connection environment (on
        * Unix, that means uid) to determine the authentication name. */
      SVN_ERR(svn_ra_svn__auth_response(conn, pool, "EXTERNAL", ""));
      return read_success(conn, pool);
  else if (find_mech(mechlist, "ANONYMOUS"))
      SVN_ERR(svn_ra_svn__auth_response(conn, pool, "ANONYMOUS", ""));
      return read_success(conn, pool);

In the cyrus-based implementation, we prefer EXTERNAL or ANONYMOUS
over everything else, in the order provided by the server:

  for (i = 0; i < mechlist->nelts; i++)
      svn_ra_svn_item_t *elt = &APR_ARRAY_IDX(mechlist, i, svn_ra_svn_item_t);

      /* Force the client to use ANONYMOUS or EXTERNAL if they are available.*/
      if (strcmp(elt->u.word, "ANONYMOUS") == 0
          || strcmp(elt->u.word, "EXTERNAL") == 0)
          mechstring = elt->u.word;

Note that the Cyrus implementation is *always used* if the client is
compiled against Cyrus.

Now note that if the server is not using Cyrus to generate its mech
string (this happens with pre-1.5.x servers all the time, or 1.5.x
servers not built with Cyrus), ANONYMOUS comes first:

 if (!needs_username && get_access(b, UNAUTHENTICATED) >= required)
    SVN_ERR(svn_ra_svn_write_word(conn, pool, "ANONYMOUS"));
  if (b->tunnel_user && get_access(b, AUTHENTICATED) >= required)
    SVN_ERR(svn_ra_svn_write_word(conn, pool, "EXTERNAL"));

This means, in practice, that if a repository allows some level of
anonymous access (say, anon-access = read but all paths are made
unreadable to all but a subset of users), and you use svn+ssh:// to
access it, a 1.4 client (or a 1.5 client without Cyrus) will start the
connection as EXTERNAL (ie, "authenticate with my ssh user") but a 1.5
client with Cyrus will start the connection as ANONYMOUS.

As I hope we all know by now, svnserve (and DAV too, to some degree)
is a little sketchy in the circumstance of "anonymous users can read
some but not all of the repository", in that it often can't actually
ask the user to upgrade to a "real" mechanism in the middle of an

In practice, what this means is that my friend reported to me that a
repository with anon-access=read but no paths readable by anyone but
specific users cannot be checked out with a 1.5.x client but can be
with a 1.4.x client. (This is with a 1.4.x server, but this should be
irrelevant.) While setting anon-access=none cures the symptom, I
really think this regression should be fixed: if the tunnel has
already set up an external user, there's no reason to ever be

I suggest the attached (untested) patch, and think it should be
backported. What do you think? (Perhaps find_mech should be shared
between the files.)

Fix regression in 1.5.x which made ra_svn clients compiled against Cyrus
use ANONYMOUS even if EXTERNAL was available.

* subversion/libsvn_ra_svn/cyrus_auth.c
  (find_mech): New (copied from internal_auth.c.)
  (svn_ra_svn__do_cyrus_auth): Prefer EXTERNAL to ANONYMOUS.


David Glasser | glasser@davidglasser.net | http://www.davidglasser.net/

To unsubscribe, e-mail: dev-unsubscribe_at_subversion.tigris.org
For additional commands, e-mail: dev-help_at_subversion.tigris.org

Received on 2008-10-23 19:09:48 CEST

This is an archived mail posted to the Subversion Dev mailing list.