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

[PATCH] optionally allow username to be passed with svnserve ANONYMOUS auth

From: Garrett Rooney <rooneg_at_electricjellyfish.net>
Date: 2003-09-14 21:03:06 CEST

As Greg Hudson suggested yesterday, a better way to get what I wanted
(usernames in my svnserve commits) would be to just pass it down as the
argument for the ANONYMOUS authentication mechanism. There is a new
command line argument (-u) for svnserve to optionally allow it to accept
these usenames and use them wherever they are required.

Any comments?

-garrett

It's sometimes nice to have usernames associated with commits that are
performed via a non-tunneled svnserve connection. This should not be the
default behavior, as such a connection is currently not making use of any
authentication mechanism, and having the default be no username at all
makes it clear that there is no certainty of who made the commit, so add a
command line option to svnserve that will cause it to believe whatever the
client tells it with regard to the username. This should obviously only
be used when the only clients that have access to the server are trusted,
as there is no mechanism for ensuring that the client doesn't lie about
their username.

* subversion/libsvn_ra_svn/client.c
  (ra_svn_open): if we do not have a username in the url, get one via the
   auth mechanisms. then, pass it along as the mecharg when sending the
   ANONYMOUS mechanism to the server.

* subversion/svnserve/server.h
  (serve): add believe_username parameter.

* subversion/svnserve/serve.c
  (serve): add believe_username parameter, and when handling the ANONYMOUS
   mechanism if believe_username is true and we have a non-empty mecharg use
   it as the username.

* subversion/svnserve/main.c
  (main): add a -u argument and if it is true set believe_username true.
   pass believe_username argument to serve in the approximately 9 million
   places we call it.
  (serve_thread_t): add believe_username member.
  (serve_thread): pass believe_username to serve.

Index: subversion/libsvn_ra_svn/client.c
===================================================================
--- subversion/libsvn_ra_svn/client.c (revision 7056)
+++ subversion/libsvn_ra_svn/client.c (working copy)
@@ -446,8 +446,28 @@
     }
   else if (find_mech(mechlist, "ANONYMOUS"))
     {
+ if (!user)
+ {
+ svn_auth_iterstate_t *iterstate;
+ const char *realmstring = apr_psprintf(pool, "<svn://%s:%d>",
+ hostname, port);
+ svn_error_t *err;
+ void *creds;
+
+ err = svn_auth_first_credentials(&creds, &iterstate,
+ SVN_AUTH_CRED_USERNAME, realmstring,
+ callbacks->auth_baton, pool);
+ if (err)
+ svn_error_clear(err);
+ else
+ user = ((svn_auth_cred_username_t *) creds)->username;
+ }
+
+ /* We send along whatever username we've got as the mechanism argument,
+ * and if the server wants, it can make use of that when committing
+ * changes. */
       SVN_ERR(svn_ra_svn_write_tuple(conn, pool, "nw(c)()", (apr_uint64_t) 1,
- "ANONYMOUS", ""));
+ "ANONYMOUS", user));
     }
   else
     return svn_error_create(SVN_ERR_RA_NOT_AUTHORIZED, NULL,
Index: subversion/svnserve/serve.c
===================================================================
--- subversion/svnserve/serve.c (revision 7056)
+++ subversion/svnserve/serve.c (working copy)
@@ -894,7 +894,7 @@
 
 svn_error_t *serve(svn_ra_svn_conn_t *conn, const char *root,
                    svn_boolean_t tunnel, svn_boolean_t read_only,
- apr_pool_t *pool)
+ svn_boolean_t believe_username, apr_pool_t *pool)
 {
   svn_error_t *err, *io_err;
   apr_uint64_t ver;
@@ -959,8 +959,14 @@
 #endif
 
   if (strcmp(mech, "ANONYMOUS") == 0)
- valid_mech = TRUE;
+ {
+ if (believe_username && mecharg && mecharg[0])
+ {
+ user = mecharg;
+ }
 
+ valid_mech = TRUE;
+ }
   if (!valid_mech) /* Client gave us an unlisted mech. */
     return SVN_NO_ERROR;
 
Index: subversion/svnserve/main.c
===================================================================
--- subversion/svnserve/main.c (revision 7056)
+++ subversion/svnserve/main.c (working copy)
@@ -79,7 +79,8 @@
   if (!progname)
     progname = "svn-server";
   fprintf(stderr,
- "Usage: %s [-X|-d|-t|-R" CONNECTION_USAGE "] [-r root]\n", progname);
+ "Usage: %s [-X|-d|-t|-R|-u" CONNECTION_USAGE "] [-r root]\n",
+ progname);
   exit(1);
 }
 
@@ -111,6 +112,7 @@
   const char *root;
   svn_ra_svn_conn_t *conn;
   svn_boolean_t read_only;
+ svn_boolean_t believe_username;
   apr_pool_t *pool;
 };
 
@@ -119,7 +121,8 @@
 {
   struct serve_thread_t *d = data;
 
- svn_error_clear(serve(d->conn, d->root, FALSE, d->read_only, d->pool));
+ svn_error_clear(serve(d->conn, d->root, FALSE, d->read_only,
+ d->believe_username, d->pool));
   svn_pool_destroy(d->pool);
 
   return NULL;
@@ -129,7 +132,7 @@
 int main(int argc, const char *const *argv)
 {
   svn_boolean_t listen_once = FALSE, daemon_mode = FALSE, tunnel_mode = FALSE;
- svn_boolean_t read_only = FALSE;
+ svn_boolean_t read_only = FALSE, believe_username = FALSE;
   apr_socket_t *sock, *usock;
   apr_file_t *in_file, *out_file;
   apr_sockaddr_t *sa;
@@ -160,7 +163,7 @@
 
   while (1)
     {
- status = apr_getopt(os, "dtXr:R" CONNECTION_OPT, &opt, &arg);
+ status = apr_getopt(os, "dtXr:Ru" CONNECTION_OPT, &opt, &arg);
       if (APR_STATUS_IS_EOF(status))
         break;
       if (status != APR_SUCCESS)
@@ -192,6 +195,10 @@
         case 'T':
           handling_mode = connection_mode_thread;
           break;
+
+ case 'u':
+ believe_username = TRUE;
+ break;
         }
     }
   if (os->ind != argc)
@@ -204,7 +211,8 @@
       apr_file_open_stdin(&in_file, pool);
       apr_file_open_stdout(&out_file, pool);
       conn = svn_ra_svn_create_conn(NULL, in_file, out_file, pool);
- svn_error_clear(serve(conn, root, tunnel_mode, read_only, pool));
+ svn_error_clear(serve(conn, root, tunnel_mode, read_only,
+ believe_username, pool));
       exit(0);
     }
 
@@ -275,7 +283,8 @@
 
       if (listen_once)
         {
- err = serve(conn, root, FALSE, read_only, connection_pool);
+ err = serve(conn, root, FALSE, read_only, believe_username,
+ connection_pool);
 
           if (listen_once && err
               && err->apr_err != SVN_ERR_RA_SVN_CONNECTION_CLOSED)
@@ -294,7 +303,7 @@
           if (status == APR_INCHILD)
             {
               svn_error_clear(serve(conn, root, FALSE, read_only,
- connection_pool));
+ believe_username, connection_pool));
               apr_socket_close(usock);
               exit(0);
             }
@@ -334,6 +343,7 @@
           thread_data->conn = conn;
           thread_data->root = root;
           thread_data->read_only = read_only;
+ thread_data->believe_username = believe_username;
           thread_data->pool = connection_pool;
           status = apr_thread_create(&tid, tattr, serve_thread, thread_data,
                                      connection_pool);
@@ -348,7 +358,8 @@
 
         case connection_mode_single:
           /* Serve one connection at a time. */
- svn_error_clear(serve(conn, root, FALSE, read_only, connection_pool));
+ svn_error_clear(serve(conn, root, FALSE, read_only, believe_username,
+ connection_pool));
           svn_pool_destroy(connection_pool);
         }
     }
Index: subversion/svnserve/server.h
===================================================================
--- subversion/svnserve/server.h (revision 7056)
+++ subversion/svnserve/server.h (working copy)
@@ -29,7 +29,7 @@
 
 svn_error_t *serve(svn_ra_svn_conn_t *conn, const char *root,
                    svn_boolean_t tunnel, svn_boolean_t read_only,
- apr_pool_t *pool);
+ svn_boolean_t believe_username, apr_pool_t *pool);
 
 #ifdef __cplusplus
 }

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Sun Sep 14 21:03:50 2003

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

This site is subject to the Apache Privacy Policy and the Apache Public Forum Archive Policy.