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

Re: sasl mechanisms order

From: Stefan Sperling <stsp_at_elego.de>
Date: Mon, 6 Sep 2010 17:35:32 +0200

On Mon, Sep 06, 2010 at 01:59:22PM +0700, Victor Sudakov wrote:
> Stefan Sperling wrote:
> > > > > Colleagues, I understand that you are expecting a patch. I am sorry, I
> > > > > am a systems administrator and not a programmer, my code writing
> > > > > ability does not go beyond scripting.
> > > >
> > > > Can you try this patch and let me know if it works?
> > >
> > > Please try this one instead, it's slightly cleaner (no functional change).
> > > Thanks.
> >
> > Ping. Did you find time to test this?
> > Should we file an issue so we don't forget about this?
>
> Sorry for the delay, I have been on vacation. Does not compile with
> your patch.

Ooops, sorry about that.
I just noticed that my svn builds didn't use SASL at all, so it compiled
for me because the code was disabled :-/

The updated diff below compiles fine for me, with SASL enabled.

Stefan

Index: subversion/libsvn_subr/config_file.c
===================================================================
--- subversion/libsvn_subr/config_file.c (revision 993034)
+++ subversion/libsvn_subr/config_file.c (working copy)
@@ -759,6 +759,11 @@ svn_config_ensure(const char *config_dir, apr_pool
                                                                              NL
         "### may be cached to disk." NL
         "### username Specifies the default username." NL
+ "### preferred-sasl-mechanism Specifies which SASL mechanism" NL
+ "### among the ones offered by the " NL
+ "### server should be tried first." NL
+ "### See the SASL documentation for" NL
+ "### a list of mechanisms available." NL
         "###" NL
         "### Set store-passwords to 'no' to avoid storing passwords in the" NL
         "### auth/ area of your config directory. It defaults to 'yes'," NL
Index: subversion/libsvn_ra_svn/cyrus_auth.c
===================================================================
--- subversion/libsvn_ra_svn/cyrus_auth.c (revision 993034)
+++ subversion/libsvn_ra_svn/cyrus_auth.c (working copy)
@@ -27,6 +27,7 @@
 #include <apr_thread_mutex.h>
 #include <apr_version.h>
 
+#include "svn_config.h"
 #include "svn_types.h"
 #include "svn_string.h"
 #include "svn_error.h"
@@ -720,6 +721,67 @@ svn_error_t *svn_ra_svn__get_addresses(const char
   return SVN_NO_ERROR;
 }
 
+
+/* Return one or more SASL mechanisms from MECHLIST.
+ * SESS is the session baton.
+ * If a preferred SASL mechanism has been defined in the configuration,
+ * prefer it if it occurs within MECHLIST. Else, fall back to EXTERNAL,
+ * then ANONYMOUS, then let SASL decide.
+ * Potentially allocate the returned list of mechanisms in RESULT_POOL.
+ * Use SCRATCH_POOL for temporary allocations. */
+static const char *
+get_sasl_mechanisms(svn_ra_svn__session_baton_t *sess,
+ apr_array_header_t *mechlist,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ const char *mechstring = "";
+ svn_config_t *cfg;
+
+ cfg = sess->config ? apr_hash_get(sess->config, SVN_CONFIG_CATEGORY_SERVERS,
+ APR_HASH_KEY_STRING) : NULL;
+ if (cfg)
+ {
+ const char *server_group;
+ const char *preferred_mech;
+
+ server_group = svn_config_find_group(cfg, sess->hostname,
+ SVN_CONFIG_SECTION_GROUPS,
+ scratch_pool);
+ if (server_group)
+ svn_config_get(cfg, &preferred_mech, server_group,
+ SVN_CONFIG_OPTION_PREFERRED_SASL_MECHANISM, NULL);
+ else
+ preferred_mech = NULL;
+
+ if (preferred_mech && svn_ra_svn__find_mech(mechlist, preferred_mech))
+ return preferred_mech;
+ }
+
+ if (svn_ra_svn__find_mech(mechlist, "EXTERNAL"))
+ return "EXTERNAL";
+ else if (svn_ra_svn__find_mech(mechlist, "ANONYMOUS"))
+ return "ANONYMOUS";
+ else
+ {
+ int i;
+
+ /* Create a string containing the list of mechanisms,
+ * separated by spaces. */
+ for (i = 0; i < mechlist->nelts; i++)
+ {
+ svn_ra_svn_item_t *elt = &APR_ARRAY_IDX(mechlist, i,
+ svn_ra_svn_item_t);
+ mechstring = apr_pstrcat(result_pool,
+ mechstring,
+ i == 0 ? "" : " ",
+ elt->u.word, NULL);
+ }
+ }
+
+ return mechstring;
+}
+
 svn_error_t *
 svn_ra_svn__do_cyrus_auth(svn_ra_svn__session_baton_t *sess,
                           apr_array_header_t *mechlist,
@@ -734,7 +796,6 @@ svn_ra_svn__do_cyrus_auth(svn_ra_svn__session_bato
      array terminator). */
   sasl_callback_t callbacks[3];
   cred_baton_t cred_baton;
- int i;
 
   if (!sess->is_tunneled)
     {
@@ -742,24 +803,7 @@ svn_ra_svn__do_cyrus_auth(svn_ra_svn__session_bato
                                         sess->conn, pool));
     }
 
- /* Prefer EXTERNAL, then ANONYMOUS, then let SASL decide. */
- if (svn_ra_svn__find_mech(mechlist, "EXTERNAL"))
- mechstring = "EXTERNAL";
- else if (svn_ra_svn__find_mech(mechlist, "ANONYMOUS"))
- mechstring = "ANONYMOUS";
- else
- {
- /* Create a string containing the list of mechanisms, separated by spaces. */
- for (i = 0; i < mechlist->nelts; i++)
- {
- svn_ra_svn_item_t *elt = &APR_ARRAY_IDX(mechlist, i, svn_ra_svn_item_t);
- mechstring = apr_pstrcat(pool,
- mechstring,
- i == 0 ? "" : " ",
- elt->u.word, NULL);
- }
- }
-
+ mechstring = get_sasl_mechanisms(sess, mechlist, pool, pool);
   realmstring = apr_psprintf(pool, "%s %s", sess->realm_prefix, realm);
 
   /* Initialize the credential baton. */
Index: subversion/libsvn_ra_svn/client.c
===================================================================
--- subversion/libsvn_ra_svn/client.c (revision 993034)
+++ subversion/libsvn_ra_svn/client.c (working copy)
@@ -715,6 +715,7 @@ static svn_error_t *ra_svn_open(svn_ra_session_t *
      reparent with a server that doesn't support reparenting. */
   SVN_ERR(open_session(&sess, url, &uri, tunnel_argv,
                        callbacks, callback_baton, sess_pool));
+ sess->config = config;
   session->priv = sess;
 
   return SVN_NO_ERROR;
Index: subversion/libsvn_ra_svn/ra_svn.h
===================================================================
--- subversion/libsvn_ra_svn/ra_svn.h (revision 993034)
+++ subversion/libsvn_ra_svn/ra_svn.h (working copy)
@@ -97,6 +97,7 @@ struct svn_ra_svn__session_baton_t {
   void *callbacks_baton;
   apr_off_t bytes_read, bytes_written; /* apr_off_t's because that's what
                                           the callback interface uses */
+ apr_hash_t *config;
 };
 
 /* Set a callback for blocked writes on conn. This handler may
Index: subversion/include/svn_config.h
===================================================================
--- subversion/include/svn_config.h (revision 993034)
+++ subversion/include/svn_config.h (working copy)
@@ -81,6 +81,7 @@ typedef struct svn_config_t svn_config_t;
 #define SVN_CONFIG_OPTION_STORE_SSL_CLIENT_CERT_PP_PLAINTEXT \
                                           "store-ssl-client-cert-pp-plaintext"
 #define SVN_CONFIG_OPTION_USERNAME "username"
+#define SVN_CONFIG_OPTION_PREFERRED_SASL_MECHANISM "preferred-sasl-mechanism"
 
 #define SVN_CONFIG_CATEGORY_CONFIG "config"
 #define SVN_CONFIG_SECTION_AUTH "auth"
Received on 2010-09-06 17:36:58 CEST

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.