As a result of the authentication discussion, I have coded up some
changes to the ra_svn protocol to make it more compatible with our
authentication infrastructure, as a prerequisite for adding CRAM
authentication and path-based authorization. Since the changes involve
modifying the initial handshake, I've bumped the protocol version to 2,
but both the client and the server support the version 1 protocol for
now. (I could have avoided bumping the protocol version, but this gets
us to a less complicated place in the long run.)
The version 1 handshake is:
SERVER: min-version max-version mech-list capability-list
CLIENT: version mechanism [ initial-token ] capability-list
[Authentication proceeds; if it fails, the connection is closed]
CLIENT: client-url
SERVER: uuid repos-root
The problems with this handshake are:
* Authentication happens before the repository is selected, so all
repositories on a server must use the same authentication
configuration.
* On the client, authentication cannot be easily delegated to a
subroutine, since the first client authentication message is
mixed in with a protocol version and capability list.
* There is no way for authentication to restart if it fails.
* Authentication exchanges which happen later in the protocol
would have to use a different format for the initial client
message.
The version 2 handshake is:
SERVER: min-version max-version mech-list(*) capability-list
CLIENT: version capability-list client-url
SERVER: mech-list realm
CLIENT: mech [ initial-token ]
[Authentication proceeds; if it fails, go back to line 4]
SERVER: uuid repos-root
* When support for version 1 is dropped, the mech-list in line 1
will become an empty list.
Also new in version 2 is the concept of authentication requests, which
are just a repeat of lines 3-5 of the above exchange. If the mechanism
list is empty, then no authentication is deemed to be required and the
client does nothing, so there is no extra round trip. Authentication
requests happen:
* Right after each command from the main set is issued.
* At the end of a commit, before commit info is sent.
* At the end of a report, for update/switch/status/diff.
With this patch, the server always makes a trivial authentication
request except at the beginning of the connection. When I add the
CRAM-MD5 code, I will try to throw in some kind of simple authorization
policy options (such as "anonymous reads and authorized writes"), and
then commit and change-rev-prop will do more interesting authentication
challenges.
I'm just about ready to commit this patch (it passes make svncheck, but
I need to do cross-version tests in both directions), but I thought I
would send it here first in case anyone has opinions.
Change ra_svn protocol to better support our authentication framework.
Protocol version is bumped to 2, but client and server both support
version 1 for the moment. In version 2, we modify the initial
handshake to support repository-specific authentication policies,
restarting authentication, and a common wire format for authentication
exchanges at the beginning of the protocol and later on. We also add
authentication exchanges at a variety of points within the protocol:
after every main-set command is issued, at the end of a commit, and at
the end of a report for update/switch/status/diff.
* libsvn_ra_svn/protocol: Update for protocol version 2.
* libsvn_ra_svn/client.c
(ra_svn_session_baton_t): To support auth requests, we need to hold
onto more than just a connection.
(ra_svn_commit_callback_baton_t, ra_svn_reporter_baton_t): Add a
pointer to the session baton in order to support auth requests at
the end of a commit and report.
(auth_response, read_success, do_auth, handle_auth_request): New
functions to handle authentication.
(make_tunnel): New function to handle tunnel initialization, in order
to improve the sanity of ra_svn_open.
(ra_svn_get_reporter): Initialize reporter baton with session baton.
(ra_svn_commit): Initialize commit baton with session baton.
(ra_svn_open): Split out tunnel initialization and authentication.
Support version 1 and 2 protocol handshake.
(ra_svn_finish_report, ra_svn_end_commit): Handle an auth request.
(ra_svn_get_latest_rev, ra_svn_get_dated_rev,
ra_svn_change_rev_prop, ra_svn_rev_proplist, ra_svn_rev_prop,
ra_svn_commit, ra_svn_get_file, ra_svn_get_dir, ra_svn_update,
ra_svn_switch, ra_svn_status, ra_svn_diff, ra_svn_log,
ra_svn_check_path): Accept a session baton instead of a connection
for the baton argument. Handle an auth request after sending the
command.
* svnserve/serve.c:
(server_baton_t): Add a protocol_version field so we know whether to
send auth requests.
(report_driver_baton_t): Add a pointer to the server baton so we can
do an auth request at the end of a report.
(trivial_auth_request): New function to send an auth request
requiring no additional authentication.
(accept_report): Initialize report baton with server baton.
(send_mechs, auth): New support functions for authentication.
(serve): Support version 1 and version 2 handshakes.
(finish_report, get_latest_rev, get_dated_rev, change_rev_prop,
rev_proplist, rev_prop, commit, get_file, get_dir, update,
switch_cmd, status, diff, log_cmd, check_path): Add trivial auth
requests.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Wed Oct 22 08:01:21 2003