On Sun, Aug 22, 2010 at 01:08:52PM +0200, Stefan Sperling wrote: > On Sun, Aug 22, 2010 at 12:56:23PM +0200, Stefan Sperling wrote: > > 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? > > 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? > > 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,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, > + const 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->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 && 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, > @@ -742,24 +804,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"