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