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"

Reply via email to