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