[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: Wed, 15 Sep 2010 13:48:10 +0200

On Tue, Sep 07, 2010 at 02:33:28PM +0700, Victor Sudakov wrote:
> This time it has compiled, but does not work.
>
> "svn list svn://admin/test/" works OK (IMHO because the ANONYMOUS
> mechanism is sufficient for that) but "svn co svn://admin/test/"
> dumps core immediately.

Hi Victor,

I hope I have found the problem. Does the patch below work better?

Thanks,
Stefan

Index: subversion/libsvn_subr/config_file.c
===================================================================
--- subversion/libsvn_subr/config_file.c (revision 997080)
+++ 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 997080)
+++ 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 997080)
+++ subversion/libsvn_ra_svn/client.c (working copy)
@@ -542,14 +542,16 @@ static svn_error_t *parse_url(const char *url, apr
 }
 
 /* Open a session to URL, returning it in *SESS_P, allocating it in POOL.
- URI is a parsed version of URL. CALLBACKS and CALLBACKS_BATON
- are provided by the caller of ra_svn_open. If tunnel_argv is non-null,
- it points to a program argument list to use when invoking the tunnel agent.
+ URI is a parsed version of URL. CONFIG is the client configuration.
+ CALLBACKS and CALLBACKS_BATON are provided by the caller of ra_svn_open.
+ If tunnel_argv is non-null, it points to a program argument list to use
+ when invoking the tunnel agent.
 */
 static svn_error_t *open_session(svn_ra_svn__session_baton_t **sess_p,
                                  const char *url,
                                  const apr_uri_t *uri,
                                  const char **tunnel_argv,
+ apr_hash_t *config,
                                  const svn_ra_callbacks2_t *callbacks,
                                  void *callbacks_baton,
                                  apr_pool_t *pool)
@@ -573,6 +575,7 @@ static svn_error_t *open_session(svn_ra_svn__sessi
   sess->callbacks = callbacks;
   sess->callbacks_baton = callbacks_baton;
   sess->bytes_read = sess->bytes_written = 0;
+ sess->config = config;
 
   if (tunnel_argv)
     SVN_ERR(make_tunnel(tunnel_argv, &conn, pool));
@@ -713,7 +716,7 @@ static svn_error_t *ra_svn_open(svn_ra_session_t *
 
   /* We open the session in a subpool so we can get rid of it if we
      reparent with a server that doesn't support reparenting. */
- SVN_ERR(open_session(&sess, url, &uri, tunnel_argv,
+ SVN_ERR(open_session(&sess, url, &uri, tunnel_argv, config,
                        callbacks, callback_baton, sess_pool));
   session->priv = sess;
 
@@ -749,7 +752,7 @@ static svn_error_t *ra_svn_reparent(svn_ra_session
   sess_pool = svn_pool_create(ra_session->pool);
   err = parse_url(url, &uri, sess_pool);
   if (! err)
- err = open_session(&new_sess, url, &uri, sess->tunnel_argv,
+ err = open_session(&new_sess, url, &uri, sess->tunnel_argv, sess->config,
                        sess->callbacks, sess->callbacks_baton, sess_pool);
   /* We destroy the new session pool on error, since it is allocated in
      the main session pool. */
Index: subversion/libsvn_ra_svn/ra_svn.h
===================================================================
--- subversion/libsvn_ra_svn/ra_svn.h (revision 997080)
+++ 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 997080)
+++ 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-15 13:50:43 CEST

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