[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: Sun, 22 Aug 2010 12:56:23 +0200

On Sun, Aug 22, 2010 at 12:17:41PM +0700, Victor Sudakov 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?
It's against latest 1.6.x, so it should apply to 1.6.12.
The patch compiles, but I have not tested it (too lazy to set up a test
scenario on a Sunday :)

It should allow you to specify a preferred SASL mechanism in the
~/.subversion/servers configuration file. If you put the option
into the [global] section it will be used for all servers, for example:

  [global]
  preferred-sasl-mechanism = GSSAPI

If you need it for specific servers only, define a server group and
put the option there (see the comments in the servers file for details).

If this works, maybe we should try to extend the new option to a list of
mechanisms, rather than just one? That might be a bit more useful.

Thanks,
Stefan

Index: subversion/libsvn_subr/config_file.c
===================================================================
--- subversion/libsvn_subr/config_file.c (revision 981459)
+++ 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/client.c
===================================================================
--- subversion/libsvn_ra_svn/client.c (revision 981459)
+++ 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 981459)
+++ 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/libsvn_ra_svn/cyrus_auth.c
===================================================================
--- subversion/libsvn_ra_svn/cyrus_auth.c (revision 981459)
+++ 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,73 @@ 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,
+ const apr_array_header_t *mechlist,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ const char *mechstring = "";
+ svn_ra_svn_item_t *elt;
+ int i;
+ 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->host,
+ 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)
+ {
+ for (i = 0; i < mechlist->nelts; i++)
+ {
+ elt = &APR_ARRAY_IDX(mechlist, i, svn_ra_svn_item_t);
+ if (strcmp(elt->u.word, preferred_mech) == 0)
+ 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
+ {
+ /* Create a string containing the list of mechanisms,
+ * separated by spaces. */
+ for (i = 0; i < mechlist->nelts; i++)
+ {
+ 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,
@@ -742,24 +810,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/include/svn_config.h
===================================================================
--- subversion/include/svn_config.h (revision 981459)
+++ 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-08-22 12:57:43 CEST

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