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;
break;
}
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
operation.
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
anonymous.
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.
]]]
--dave
--
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