Index: subversion/include/private/svn_sasl.h =================================================================== --- subversion/include/private/svn_sasl.h (revision 0) +++ subversion/include/private/svn_sasl.h (revision 0) @@ -0,0 +1,57 @@ +/* + * svn_sasl.h : SASL-related declarations shared between the + * ra_svn and svnserve module + * + * ==================================================================== + * Copyright (c) 2006 CollabNet. All rights reserved. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://subversion.tigris.org/license-1.html. + * If newer versions of this license are posted there, you may use a + * newer version instead, at your option. + * + * This software consists of voluntary contributions made by many + * individuals. For exact contribution history, see the revision + * history and logs, available at http://subversion.tigris.org/. + * ==================================================================== + */ + + + +#ifndef SVN_SASL_H +#define SVN_SASL_H + +#ifdef WIN32 +/* This prevents sasl.h from redefining iovec, which is always defined by APR + on win32. */ +#define STRUCT_IOVEC_DEFINED +#include +#else +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +extern volatile svn_atomic_t svn_ra_svn__sasl_status; + +/* Initialize secprops with default values. */ +void svn_ra_svn__default_secprops(sasl_security_properties_t *secprops); + +/* This function is called by the client and the server before + calling sasl_{client, server}_init. */ +apr_status_t svn_ra_svn__sasl_common_init(void); + +/* Sets local_addrport and remote_addrport to a string containing the + remote and local IP address and port, formatted like this: a.b.c.d;port. */ +svn_error_t *svn_ra_svn__get_addresses(const char **local_addrport, + const char **remote_addrport, + svn_ra_svn_conn_t *conn, + apr_pool_t *pool); +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* SVN_SASL_H */ Index: subversion/libsvn_ra_svn/ra_svn_sasl.h =================================================================== --- subversion/libsvn_ra_svn/ra_svn_sasl.h (revision 21556) +++ subversion/libsvn_ra_svn/ra_svn_sasl.h (working copy) @@ -1,69 +0,0 @@ -/* - * ra_svn_sasl.h : SASL-related declarations shared between the - * ra_svn and svnserve module - * - * ==================================================================== - * Copyright (c) 2006 CollabNet. All rights reserved. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at http://subversion.tigris.org/license-1.html. - * If newer versions of this license are posted there, you may use a - * newer version instead, at your option. - * - * This software consists of voluntary contributions made by many - * individuals. For exact contribution history, see the revision - * history and logs, available at http://subversion.tigris.org/. - * ==================================================================== - */ - - - -#ifndef RA_SVN_SASL_H -#define RA_SVN_SASL_H - -#ifdef WIN32 -/* This prevents sasl.h from redefining iovec, which is always defined by APR - on win32. */ -#define STRUCT_IOVEC_DEFINED -#include -#else -#include -#endif - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -#include "ra_svn.h" /* for SVN_RA_SVN__READBUF_SIZE */ - -extern volatile svn_atomic_t svn_ra_svn__sasl_status; - -/* Define sane defaults for a sasl_security_properties_t structure. - The first two values are the minimum and maximum encryption strengths - that the chosen SASL mechanism should provide. 0 means 'no encryption', - 256 means '256-bit encryption', which is about the best that any SASL - mechanism can provide. Using these values effectively means 'use whatever - encryption the other side wants'. Note that SASL will try to use better - encryption whenever possible, so if both the server and the client use - these values the highest possible encryption strength will be used. - The third value, the connection's read buffer size, needs to be - commmunicated to the peer if a security layer is negotiated. */ -#define SVN_RA_SVN__DEFAULT_SECPROPS {0, 256, SVN_RA_SVN__READBUF_SIZE, \ - 0, NULL, NULL} - -/* This function is called by the client and the server before - calling sasl_{client, server}_init. */ -apr_status_t svn_ra_svn__sasl_common_init(void); - -/* Sets local_addrport and remote_addrport to a string containing the - remote and local IP address and port, formatted like this: a.b.c.d;port. */ -svn_error_t *svn_ra_svn__get_addresses(const char **local_addrport, - const char **remote_addrport, - apr_socket_t *sock, - apr_pool_t *pool); -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* RA_SVN_SASL_H */ Index: subversion/libsvn_ra_svn/sasl_auth.c =================================================================== --- subversion/libsvn_ra_svn/sasl_auth.c (revision 21556) +++ subversion/libsvn_ra_svn/sasl_auth.c (working copy) @@ -36,9 +36,9 @@ #include "svn_base64.h" #include "private/svn_atomic.h" +#include "private/svn_sasl.h" #include "ra_svn.h" -#include "ra_svn_sasl.h" /* Note: In addition to being used via svn_atomic_init_once to control * initialization of the SASL code this will also be referenced in @@ -195,6 +195,28 @@ return APR_SUCCESS; } +void svn_ra_svn__default_secprops(sasl_security_properties_t *secprops) +{ + /* The minimum and maximum security strength factors that the chosen + SASL mechanism should provide. 0 means 'no encryption', 256 means + '256-bit encryption', which is about the best that any SASL + mechanism can provide. Using these values effectively means 'use + whatever encryption the other side wants'. Note that SASL will try + to use better encryption whenever possible, so if both the server and + the client use these values the highest possible encryption strength + will be used. */ + secprops->min_ssf = 0; + secprops->max_ssf = 256; + + /* Set maxbufsize to the maximum amount of data we can read at any one time. + This value needs to be commmunicated to the peer if a security layer + is negotiated. */ + secprops->maxbufsize = SVN_RA_SVN__READBUF_SIZE; + + secprops->security_flags = 0; + secprops->property_names = secprops->property_values = NULL; +} + /* Create a new SASL context. */ static svn_error_t *new_sasl_ctx(sasl_conn_t **sasl_ctx, svn_boolean_t is_tunneled, @@ -203,7 +225,7 @@ const char *remote_addrport, apr_pool_t *pool) { - sasl_security_properties_t secprops = SVN_RA_SVN__DEFAULT_SECPROPS; + sasl_security_properties_t secprops; int result; result = sasl_client_new("svn", hostname, local_addrport, remote_addrport, @@ -232,6 +254,7 @@ /* Set security properties. Don't allow PLAIN or LOGIN, since we don't support TLS yet. */ + svn_ra_svn__default_secprops(&secprops); secprops.security_flags = SASL_SEC_NOPLAINTEXT; sasl_setprop(*sasl_ctx, SASL_SEC_PROPS, &secprops); @@ -395,36 +418,38 @@ } svn_error_t *svn_ra_svn__get_addresses(const char **local_addrport, - const char **remote_addrport, - apr_socket_t *sock, - apr_pool_t *pool) + const char **remote_addrport, + svn_ra_svn_conn_t *conn, + apr_pool_t *pool) { - apr_status_t apr_err; - apr_sockaddr_t *local_sa, *remote_sa; - char *local_addr, *remote_addr; + if (conn->sock) + { + apr_status_t apr_err; + apr_sockaddr_t *local_sa, *remote_sa; + char *local_addr, *remote_addr; - apr_err = apr_socket_addr_get(&local_sa, APR_LOCAL, sock); - if (apr_err) - return svn_error_wrap_apr(apr_err, NULL); + apr_err = apr_socket_addr_get(&local_sa, APR_LOCAL, conn->sock); + if (apr_err) + return svn_error_wrap_apr(apr_err, NULL); - apr_err = apr_socket_addr_get(&remote_sa, APR_REMOTE, sock); - if (apr_err) - return svn_error_wrap_apr(apr_err, NULL); + apr_err = apr_socket_addr_get(&remote_sa, APR_REMOTE, conn->sock); + if (apr_err) + return svn_error_wrap_apr(apr_err, NULL); - apr_err = apr_sockaddr_ip_get(&local_addr, local_sa); - if (apr_err) - return svn_error_wrap_apr(apr_err, NULL); + apr_err = apr_sockaddr_ip_get(&local_addr, local_sa); + if (apr_err) + return svn_error_wrap_apr(apr_err, NULL); - apr_err = apr_sockaddr_ip_get(&remote_addr, remote_sa); - if (apr_err) - return svn_error_wrap_apr(apr_err, NULL); + apr_err = apr_sockaddr_ip_get(&remote_addr, remote_sa); + if (apr_err) + return svn_error_wrap_apr(apr_err, NULL); - /* Format the IP address and port number like this: a.b.c.d;port */ - *local_addrport = apr_pstrcat(pool, local_addr, ";", - apr_itoa(pool, (int)local_sa->port), NULL); - *remote_addrport = apr_pstrcat(pool, remote_addr, ";", - apr_itoa(pool, (int)remote_sa->port), NULL); - + /* Format the IP address and port number like this: a.b.c.d;port */ + *local_addrport = apr_pstrcat(pool, local_addr, ";", + apr_itoa(pool, (int)local_sa->port), NULL); + *remote_addrport = apr_pstrcat(pool, remote_addr, ";", + apr_itoa(pool, (int)remote_sa->port), NULL); + } return SVN_NO_ERROR; } @@ -461,7 +486,7 @@ if (!sess->is_tunneled) { SVN_ERR(svn_ra_svn__get_addresses(&local_addrport, &remote_addrport, - sess->conn->sock, pool)); + sess->conn, pool)); SVN_ERR(get_remote_hostname(&hostname, sess->conn->sock)); } Index: subversion/svnserve/sasl_auth.c =================================================================== --- subversion/svnserve/sasl_auth.c (revision 21556) +++ subversion/svnserve/sasl_auth.c (working copy) @@ -35,7 +35,7 @@ #include "server.h" -#include "../libsvn_ra_svn/ra_svn_sasl.h" +#include "private/svn_sasl.h" /* SASL calls this function before doing anything with a username, which gives us an opportunity to do some sanity-checking. If the username contains @@ -213,23 +213,6 @@ return SVN_NO_ERROR; } -static svn_error_t *get_local_hostname(char **hostname, - apr_socket_t *sock) -{ - apr_status_t apr_err; - apr_sockaddr_t *sa; - - apr_err = apr_socket_addr_get(&sa, APR_LOCAL, sock); - if (apr_err) - return svn_error_wrap_apr(apr_err, NULL); - - apr_err = apr_getnameinfo(hostname, sa, 0); - if (apr_err) - return svn_error_wrap_apr(apr_err, NULL); - - return SVN_NO_ERROR; -} - static apr_status_t sasl_dispose_cb(void *data) { sasl_conn_t *sasl_ctx = (sasl_conn_t*) data; @@ -245,18 +228,22 @@ { sasl_conn_t *sasl_ctx; apr_pool_t *subpool; + apr_status_t apr_err; const char *localaddrport = NULL, *remoteaddrport = NULL; const char *mechlist; - char *hostname = NULL; - sasl_security_properties_t secprops = SVN_RA_SVN__DEFAULT_SECPROPS; + char hostname[APRMAXHOSTLEN + 1]; + sasl_security_properties_t secprops; svn_boolean_t success, no_anonymous; int mech_count, result = SASL_OK; - if (conn->sock) + SVN_ERR(svn_ra_svn__get_addresses(&localaddrport, &remoteaddrport, + conn, pool)); + apr_err = apr_gethostname(hostname, sizeof(hostname), pool); + if (apr_err) { - SVN_ERR(svn_ra_svn__get_addresses(&localaddrport, &remoteaddrport, - conn->sock, pool)); - SVN_ERR(get_local_hostname(&hostname, conn->sock)); + svn_error_t *err = svn_error_wrap_apr(apr_err, _("Can't get hostname")); + SVN_ERR(svn_ra_svn_write_cmd_failure(conn, pool, err)); + return svn_ra_svn_flush(conn, pool); } /* Create a SASL context. SASL_SUCCESS_DATA tells SASL that the protocol @@ -278,6 +265,9 @@ apr_pool_cleanup_register(pool, sasl_ctx, sasl_dispose_cb, apr_pool_cleanup_null); + /* Initialize security properties. */ + svn_ra_svn__default_secprops(&secprops); + /* Don't allow PLAIN or LOGIN, since we don't support TLS yet. */ secprops.security_flags = SASL_SEC_NOPLAINTEXT;