On 6/14/13 5:20 AM, Ben Reser wrote:
> Actually now that I think about it a bit more I'm not sure that helps.
>  It'll probably just shift it to a link time error because the defines
> will be there so it'll build, SWIG will generate wrappers for them
> that depend on the functions in our libraries, which won't be
> available in the libraries they built because we exclude them on their
> platform.
> 
> We can work around that by adding logic to SWIG to specifically
> exclude these functions based on the same conditions as we have in our
> headers and build systems.  But then we've added yet another place to
> maintain this.
> 
> So it turns into hacks all the way down.
> 
> The alternative is to fix it so the error happens at runtime, which
> shifts that to the library user.  In these specific cases, simply
> providing a noop provider, hides the entire problem from even the
> library user.

So fixing this doesn't require this level of effort.  Daniel's original
suggestion actually would have worked fine for a couple of reasons.

1) The problem is actually caused by r1241554 and the various follow ups trying
to fix it.  This change added support for the callback for retrieving the
gnome-keyring passphrase from the user to unlock the keyring to the bindings.
Having the typedef even when the gnome keyring isn't built is no problem since
even if a client registers the callback it'll never be called and there's
really nothing specific to gnome-keyring about it.  So this typedef and the
supporting constants shouldn't have been excluded based on platform.

2) We already exclude the platform specific provider functions from the
bindings.  So the problem I was concerned about at link time doesn't happen.

They can still use platform specific providers they just need to use
svn_auth_get_platform_specific_provider() or
svn_auth_get_platform_specific_client_providers().

So the fix I'm about to commit simply moves the #if directive down so that the
typedef and macros are available regardless of platform.

We still could go to the effort of making all of the auth apis available
regardless of platform and providing noop implementations of the functions on
platforms without the support.  But we'd have to build the
libsvn_auth_gnome_keyring and libsvn_auth_kwallet libraries on all platforms
(though not linked against gnome or kwallet unless they were found/enabled).
We'd have to do this because we can't move the symbols between libraries
without breaking the ABI.  Anyone uses the
svn_auth_get_{gnome_keyring,kwallet)_*() functions has to be loading the
dynamic library and then doing a symbol search.

To that end I produced a patch (which I've attached for posterity's sake).  But
I don't see a reason to actually apply it.  The only benefit would be allowing
cross platform clients to use these apis without caring about the platform or
to allow libraries on clients to be replaced without making sure to match the
platform specific auth support that their original library had if they're using
it.  So until such a time that someone shows up with such a problem I'm
inclined to punt on this issue.

For that matter I intend to mark these get apis as deprecated by the
svn_auth_get_platform_specific_provider() or
svn_get_get_platform_specific_client_providers() apis.
Index: configure.ac
===================================================================
--- configure.ac        (revision 1543908)
+++ configure.ac        (working copy)
@@ -859,10 +859,10 @@ AS_HELP_STRING([--disable-plaintext-password-stora
 
 dnl Build and install rules -------------------
 
-INSTALL_STATIC_RULES="install-bin install-docs"
-INSTALL_RULES="install-fsmod-lib install-ramod-lib install-lib install-include 
install-static"
+INSTALL_STATIC_RULES="install-bin install-docs install-kwallet-lib 
install-gnome-keyring-lib"
+INSTALL_RULES="install-fsmod-lib install-ramod-lib install-lib 
install-kwallet-lib install-gnome-keyring-lib install-include install-static"
 INSTALL_RULES="$INSTALL_RULES $INSTALL_APACHE_RULE"
-BUILD_RULES="fsmod-lib ramod-lib lib bin test sub-test $BUILD_APACHE_RULE 
tools"
+BUILD_RULES="fsmod-lib ramod-lib lib bin test sub-test $BUILD_APACHE_RULE 
tools kwallet-lib gnome-keyring-lib"
 
 if test "$svn_lib_berkeley_db" = "yes"; then
   BUILD_RULES="$BUILD_RULES bdb-lib bdb-test"
@@ -878,18 +878,6 @@ if test "$svn_lib_serf" = "yes"; then
   INSTALL_STATIC_RULES="$INSTALL_STATIC_RULES install-serf-lib"
 fi
 
-if test "$svn_lib_kwallet" = "yes"; then
-  BUILD_RULES="$BUILD_RULES kwallet-lib"
-  INSTALL_RULES="`echo $INSTALL_RULES | $SED 's/install-lib/install-lib 
install-kwallet-lib/'`"
-  INSTALL_STATIC_RULES="$INSTALL_STATIC_RULES install-kwallet-lib"
-fi
-
-if test "$found_gnome_keyring" = "yes"; then
-  BUILD_RULES="$BUILD_RULES gnome-keyring-lib"
-  INSTALL_RULES="`echo $INSTALL_RULES | $SED 's/install-lib/install-lib 
install-gnome-keyring-lib/'`"
-  INSTALL_STATIC_RULES="$INSTALL_STATIC_RULES install-gnome-keyring-lib"
-fi
-
 if test "$USE_NLS" = "yes"; then
   BUILD_RULES="$BUILD_RULES locale"
   INSTALL_RULES="$INSTALL_RULES install-locale"
Index: subversion/include/private/svn_auth_private.h
===================================================================
--- subversion/include/private/svn_auth_private.h       (revision 1543908)
+++ subversion/include/private/svn_auth_private.h       (working copy)
@@ -249,7 +249,44 @@ svn_auth__get_windows_ssl_server_authority_provide
                             apr_pool_t *pool);
 #endif
 
+/**
+ * Set @a *provider to an authentication provider that implements a
+ * no operation simple provider.
+ *
+ * This function exists to allow get functions for platform specific
+ * providers to still exist in our API even when the provider is not
+ * available.
+ */
+void
+svn_auth__get_noop_simple_provider(svn_auth_provider_object_t **provider,
+                                   apr_pool_t *pool);
 
+/**
+ * Set @a *provider to an authentication provider that implements a
+ * no operation SSL client cert password provider
+ *
+ * This function exists to allow get functions for platform specific
+ * providers to still exist in our API even when the provider is not
+ * available.
+ */
+void
+svn_auth__get_noop_ssl_client_cert_pw_provider
+   (svn_auth_provider_object_t **provider,
+    apr_pool_t *pool);
+
+/**
+ * Set @a *provider to an authentication provider that implements a
+ * no operation SSL server trust provider
+ *
+ * This function exists to allow get functions for platform specific
+ * providers to still exist in our API even when the provider is not
+ * available.
+ */
+void
+svn_auth__get_noop_ssl_server_trust_provider
+   (svn_auth_provider_object_t **provider,
+    apr_pool_t *pool);
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
Index: subversion/include/svn_auth.h
===================================================================
--- subversion/include/svn_auth.h       (revision 1543908)
+++ subversion/include/svn_auth.h       (working copy)
@@ -865,7 +865,6 @@ svn_auth_get_platform_specific_client_providers(
   svn_config_t *config,
   apr_pool_t *pool);
 
-#if (defined(WIN32) && !defined(__MINGW32__)) || defined(DOXYGEN)
 /**
  * Set @a *provider to an authentication provider of type @c
  * svn_auth_cred_simple_t that gets/sets information from the user's
@@ -929,9 +928,6 @@ svn_auth_get_windows_ssl_server_trust_provider(
   svn_auth_provider_object_t **provider,
   apr_pool_t *pool);
 
-#endif /* WIN32 && !__MINGW32__ || DOXYGEN */
-
-#if defined(DARWIN) || defined(DOXYGEN)
 /**
  * Set @a *provider to an authentication provider of type @c
  * svn_auth_cred_simple_t that gets/sets information from the user's
@@ -964,9 +960,7 @@ void
 svn_auth_get_keychain_ssl_client_cert_pw_provider(
   svn_auth_provider_object_t **provider,
   apr_pool_t *pool);
-#endif /* DARWIN || DOXYGEN */
 
-#if (!defined(DARWIN) && !defined(WIN32)) || defined(DOXYGEN)
 /** A type of callback function for obtaining the GNOME Keyring password.
  *
  * In this callback, the client should ask the user for default keyring
@@ -1104,9 +1098,7 @@ void
 svn_auth_get_kwallet_ssl_client_cert_pw_provider(
   svn_auth_provider_object_t **provider,
   apr_pool_t *pool);
-#endif /* (!DARWIN && !WIN32) || DOXYGEN */
 
-#if !defined(WIN32) || defined(DOXYGEN)
 /**
  * Set @a *provider to an authentication provider of type @c
  * svn_auth_cred_simple_t that gets/sets information from the user's
@@ -1126,9 +1118,7 @@ void
 svn_auth_get_gpg_agent_simple_provider
     (svn_auth_provider_object_t **provider,
      apr_pool_t *pool);
-#endif /* !defined(WIN32) || defined(DOXYGEN) */
 
-
 /** Set @a *provider to an authentication provider of type @c
  * svn_auth_cred_username_t that gets/sets information from a user's
  * ~/.subversion configuration directory.  Allocate @a *provider in
Index: subversion/libsvn_auth_gnome_keyring/gnome_keyring.c
===================================================================
--- subversion/libsvn_auth_gnome_keyring/gnome_keyring.c        (revision 
1543908)
+++ subversion/libsvn_auth_gnome_keyring/gnome_keyring.c        (working copy)
@@ -29,8 +29,10 @@
 
 #include <apr_pools.h>
 #include <apr_strings.h>
+#ifdef SVN_HAVE_GNOME_KEYRING
 #include <glib.h>
 #include <gnome-keyring.h>
+#endif
 
 #include "svn_private_config.h"
 #include "svn_auth.h"
@@ -47,7 +49,7 @@
 /* GNOME Keyring simple provider, puts passwords in GNOME Keyring        */
 /*-----------------------------------------------------------------------*/
 
-
+#ifdef SVN_HAVE_GNOME_KEYRING
 struct gnome_keyring_baton
 {
   const char *keyring_name;
@@ -442,6 +444,8 @@ static const svn_auth_provider_t gnome_keyring_sim
   simple_gnome_keyring_save_creds
 };
 
+#endif /* SVN_HAVE_GNOME_KEYRING */
+
 /* Public API */
 void
 svn_auth_get_gnome_keyring_simple_provider
@@ -448,6 +452,7 @@ svn_auth_get_gnome_keyring_simple_provider
     (svn_auth_provider_object_t **provider,
      apr_pool_t *pool)
 {
+#ifdef SVN_HAVE_GNOME_KEYRING
   svn_auth_provider_object_t *po = apr_pcalloc(pool, sizeof(*po));
 
   po->vtable = &gnome_keyring_simple_provider;
@@ -454,6 +459,9 @@ svn_auth_get_gnome_keyring_simple_provider
   *provider = po;
 
   init_gnome_keyring();
+#else
+  return svn_auth__get_noop_simple_provider(provider, pool);
+#endif
 }
 
 
@@ -462,6 +470,7 @@ svn_auth_get_gnome_keyring_simple_provider
 /* puts passphrases in GNOME Keyring                                     */
 /*-----------------------------------------------------------------------*/
 
+#ifdef SVN_HAVE_GNOME_KEYRING
 /* Get cached encrypted credentials from the ssl client cert password
    provider's cache. */
 static svn_error_t *
@@ -500,6 +509,7 @@ static const svn_auth_provider_t gnome_keyring_ssl
   NULL,
   ssl_client_cert_pw_gnome_keyring_save_creds
 };
+#endif /* SVN_HAVE_GNOME_KEYRING */
 
 /* Public API */
 void
@@ -507,6 +517,7 @@ svn_auth_get_gnome_keyring_ssl_client_cert_pw_prov
     (svn_auth_provider_object_t **provider,
      apr_pool_t *pool)
 {
+#ifdef SVN_HAVE_GNOME_KEYRING
   svn_auth_provider_object_t *po = apr_pcalloc(pool, sizeof(*po));
 
   po->vtable = &gnome_keyring_ssl_client_cert_pw_provider;
@@ -513,4 +524,7 @@ svn_auth_get_gnome_keyring_ssl_client_cert_pw_prov
   *provider = po;
 
   init_gnome_keyring();
+#else
+  return svn_auth__get_noop_ssl_client_cert_pw_provider(provider, pool);
+#endif
 }
Index: subversion/libsvn_auth_kwallet/kwallet.cpp
===================================================================
--- subversion/libsvn_auth_kwallet/kwallet.cpp  (revision 1543908)
+++ subversion/libsvn_auth_kwallet/kwallet.cpp  (working copy)
@@ -34,6 +34,7 @@
 #include <apr_pools.h>
 #include <apr_strings.h>
 
+#ifdef SVN_HAVE_KWALLET
 #include <dbus/dbus.h>
 #include <QtCore/QCoreApplication>
 #include <QtCore/QString>
@@ -43,6 +44,7 @@
 #include <kcomponentdata.h>
 #include <klocalizedstring.h>
 #include <kwallet.h>
+#endif
 
 #include "svn_auth.h"
 #include "svn_config.h"
@@ -61,6 +63,7 @@
 /* KWallet simple provider, puts passwords in KWallet                    */
 /*-----------------------------------------------------------------------*/
 
+#ifdef SVN_HAVE_KWALLET
 static int q_argc = 1;
 static char q_argv0[] = "svn"; // Build non-const char * from string constant
 static char *q_argv[] = { q_argv0 };
@@ -378,6 +381,7 @@ static const svn_auth_provider_t kwallet_simple_pr
   NULL,
   kwallet_simple_save_creds
 };
+#endif /* SVN_HAVE_KWALLET */
 
 /* Public API */
 extern "C" {
@@ -385,11 +389,15 @@ void
 svn_auth_get_kwallet_simple_provider(svn_auth_provider_object_t **provider,
                                      apr_pool_t *pool)
 {
+#ifdef SVN_HAVE_KWALLET
   svn_auth_provider_object_t *po =
     static_cast<svn_auth_provider_object_t *> (apr_pcalloc(pool, sizeof(*po)));
 
   po->vtable = &kwallet_simple_provider;
   *provider = po;
+#else
+  return svn_auth__get_noop_simple_provider(provider, pool);
+#endif
 }
 }
 
@@ -399,6 +407,7 @@ svn_auth_get_kwallet_simple_provider(svn_auth_prov
 /* puts passphrases in KWallet                                           */
 /*-----------------------------------------------------------------------*/
 
+#ifdef SVN_HAVE_KWALLET
 /* Get cached encrypted credentials from the ssl client cert password
    provider's cache. */
 static svn_error_t *
@@ -441,6 +450,7 @@ static const svn_auth_provider_t kwallet_ssl_clien
   NULL,
   kwallet_ssl_client_cert_pw_save_creds
 };
+#endif /* SVN_HAVE_KWALLET */
 
 /* Public API */
 extern "C" {
@@ -449,10 +459,14 @@ svn_auth_get_kwallet_ssl_client_cert_pw_provider
     (svn_auth_provider_object_t **provider,
      apr_pool_t *pool)
 {
+#ifdef SVN_HAVE_KWALLET
   svn_auth_provider_object_t *po =
     static_cast<svn_auth_provider_object_t *> (apr_pcalloc(pool, sizeof(*po)));
 
   po->vtable = &kwallet_ssl_client_cert_pw_provider;
   *provider = po;
+#else
+  return svn_auth__get_noop_ssl_client_cert_pw_provider(provider, pool);
+#endif
 }
 }
Index: subversion/libsvn_subr/auth.c
===================================================================
--- subversion/libsvn_subr/auth.c       (revision 1543908)
+++ subversion/libsvn_subr/auth.c       (working copy)
@@ -677,3 +677,71 @@ svn_auth_get_platform_specific_client_providers(ap
 
   return SVN_NO_ERROR;
 }
+
+/* No Operation Auth Providers */
+static svn_error_t *
+noop_provider_first_creds(void **credentials,
+                          void **iter_baton,
+                          void *provider_baton,
+                          apr_hash_t *parameters,
+                          const char *realmstring,
+                          apr_pool_t *pool)
+{
+  *credentials = NULL;
+  *iter_baton = NULL;
+  return SVN_NO_ERROR;
+}
+
+static const svn_auth_provider_t noop_simple_provider = {
+  SVN_AUTH_CRED_SIMPLE,
+  noop_provider_first_creds,
+  NULL,
+  NULL
+};
+
+void
+svn_auth__get_noop_simple_provider(svn_auth_provider_object_t **provider,
+                                   apr_pool_t *pool)
+{
+  svn_auth_provider_object_t *po = apr_pcalloc(pool, sizeof(*po));
+
+  po->vtable = &noop_simple_provider;
+  *provider = po;
+}
+
+static const svn_auth_provider_t noop_ssl_client_cert_pw_provider = {
+  SVN_AUTH_CRED_SSL_CLIENT_CERT_PW,
+  noop_provider_first_creds,
+  NULL,
+  NULL
+};
+
+void
+svn_auth__get_noop_ssl_client_cert_pw_provider
+   (svn_auth_provider_object_t **provider,
+    apr_pool_t *pool)
+{
+  svn_auth_provider_object_t *po = apr_pcalloc(pool, sizeof(*po));
+
+  po->vtable = &noop_ssl_client_cert_pw_provider;
+  *provider = po;
+}
+
+static const svn_auth_provider_t noop_ssl_server_trust_provider = {
+  SVN_AUTH_CRED_SSL_SERVER_TRUST,
+  noop_provider_first_creds,
+  NULL,
+  NULL 
+};
+
+void
+svn_auth__get_noop_ssl_server_trust_provider
+   (svn_auth_provider_object_t **provider,
+    apr_pool_t *pool)
+{
+  svn_auth_provider_object_t *po = apr_pcalloc(pool, sizeof(*po));
+
+  po->vtable = &noop_ssl_server_trust_provider;
+  *provider = po;
+}
+
Index: subversion/libsvn_subr/gpg_agent.c
===================================================================
--- subversion/libsvn_subr/gpg_agent.c  (revision 1543908)
+++ subversion/libsvn_subr/gpg_agent.c  (working copy)
@@ -64,6 +64,8 @@
 #include <sys/socket.h>
 #include <sys/un.h>
 
+#endif /* !WIN32 */
+
 #include <apr_pools.h>
 #include "svn_auth.h"
 #include "svn_config.h"
@@ -77,7 +79,7 @@
 
 #include "svn_private_config.h"
 
-#ifdef SVN_HAVE_GPG_AGENT
+#if defined(SVN_HAVE_GPG_AGENT) && !defined(WIN32)
 
 #define BUFFER_SIZE 1024
 
@@ -472,17 +474,21 @@ static const svn_auth_provider_t gpg_agent_simple_
   simple_gpg_agent_save_creds
 };
 
+#endif /* defined(SVN_HAVE_GPG_AGENT) && !defined(WIN32) */
 
+
 /* Public API */
 void
 svn_auth_get_gpg_agent_simple_provider(svn_auth_provider_object_t **provider,
                                        apr_pool_t *pool)
 {
+#if defined(SVN_HAVE_GPG_AGENT) && !defined(WIN32)
   svn_auth_provider_object_t *po = apr_pcalloc(pool, sizeof(*po));
 
   po->vtable = &gpg_agent_simple_provider;
   *provider = po;
+#else
+  return svn_auth__get_noop_simple_provider(provider, pool);
+#endif
 }
 
-#endif /* SVN_HAVE_GPG_AGENT */
-#endif /* !WIN32 */
Index: subversion/libsvn_subr/macos_keychain.c
===================================================================
--- subversion/libsvn_subr/macos_keychain.c     (revision 1543908)
+++ subversion/libsvn_subr/macos_keychain.c     (working copy)
@@ -237,6 +237,7 @@ static const svn_auth_provider_t keychain_ssl_clie
   NULL,
   keychain_ssl_client_cert_pw_save_creds
 };
+#endif /* SVN_HAVE_KEYCHAIN_SERVICES */
 
 
 /* Public API */
@@ -244,10 +245,14 @@ void
 svn_auth_get_keychain_simple_provider(svn_auth_provider_object_t **provider,
                                       apr_pool_t *pool)
 {
+#ifdef SVN_HAVE_KEYCHAIN_SERVICES
   svn_auth_provider_object_t *po = apr_pcalloc(pool, sizeof(*po));
 
   po->vtable = &keychain_simple_provider;
   *provider = po;
+#else
+  return svn_auth__get_noop_simple_provider(provider, pool);
+#endif
 }
 
 void
@@ -255,9 +260,12 @@ svn_auth_get_keychain_ssl_client_cert_pw_provider
   (svn_auth_provider_object_t **provider,
    apr_pool_t *pool)
 {
+#ifdef SVN_HAVE_KEYCHAIN_SERVICES
   svn_auth_provider_object_t *po = apr_pcalloc(pool, sizeof(*po));
 
   po->vtable = &keychain_ssl_client_cert_pw_provider;
   *provider = po;
+#else
+  return svn_auth__get_noop_ssl_client_cert_pw_provider(provider, pool);
+#endif
 }
-#endif /* SVN_HAVE_KEYCHAIN_SERVICES */
Index: subversion/libsvn_subr/win32_crypto.c
===================================================================
--- subversion/libsvn_subr/win32_crypto.c       (revision 1543908)
+++ subversion/libsvn_subr/win32_crypto.c       (working copy)
@@ -21,12 +21,8 @@
  * ====================================================================
  */
 
-/* prevent "empty compilation unit" warning on e.g. UNIX */
-typedef int win32_crypto__dummy;
-
 /* ==================================================================== */
 
-#if defined(WIN32) && !defined(__MINGW32__)
 
 /*** Includes. ***/
 
@@ -44,6 +40,8 @@
 
 #include "private/svn_auth_private.h"
 
+#if defined(WIN32) && !defined(__MINGW32__)
+
 #include <wincrypt.h>
 
 
@@ -210,6 +208,7 @@ static const svn_auth_provider_t windows_simple_pr
   windows_simple_save_creds
 };
 
+#endif /* WIN32 */
 
 /* Public API */
 void
@@ -216,12 +215,19 @@ void
 svn_auth_get_windows_simple_provider(svn_auth_provider_object_t **provider,
                                      apr_pool_t *pool)
 {
+#if defined(WIN32) && !defined(__MINGW32__)
   svn_auth_provider_object_t *po = apr_pcalloc(pool, sizeof(*po));
 
   po->vtable = &windows_simple_provider;
   *provider = po;
+#else
+  return svn_auth__get_noop_simple_provider(provider, pool);
+#endif
+
 }
 
+#if defined(WIN32) && !defined(__MINGW32__)
+
 
 /*-----------------------------------------------------------------------*/
 /* Windows SSL server trust provider, validates ssl certificate using    */
@@ -328,6 +334,7 @@ static const svn_auth_provider_t windows_ssl_clien
   windows_ssl_client_cert_pw_save_creds
 };
 
+#endif /* WIN32 */
 
 /* Public API */
 void
@@ -335,12 +342,18 @@ svn_auth_get_windows_ssl_client_cert_pw_provider
    (svn_auth_provider_object_t **provider,
     apr_pool_t *pool)
 {
+#if defined(WIN32) && !defined(__MINGW32__)
   svn_auth_provider_object_t *po = apr_pcalloc(pool, sizeof(*po));
 
   po->vtable = &windows_ssl_client_cert_pw_provider;
   *provider = po;
+#else
+  return svn_auth__get_noop_ssl_client_cert_pw_provider(provider, pool);
+#endif
 }
 
+#if defined(WIN32) && !defined(__MINGW32__)
+
 
 /*-----------------------------------------------------------------------*/
 /* Windows SSL server trust provider, validates ssl certificate using    */
@@ -480,17 +493,25 @@ static const svn_auth_provider_t windows_server_tr
   NULL,
 };
 
+#endif /* WIN32 */
+
 /* Public API */
 void
 svn_auth_get_windows_ssl_server_trust_provider
   (svn_auth_provider_object_t **provider, apr_pool_t *pool)
 {
+#if defined(WIN32) && !defined(__MINGW32__)
   svn_auth_provider_object_t *po = apr_pcalloc(pool, sizeof(*po));
 
   po->vtable = &windows_server_trust_provider;
   *provider = po;
+#else
+  return svn_auth__get_noop_ssl_server_trust_provider(provider, pool);
+#endif
 }
 
+#if defined(WIN32) && !defined(__MINGW32__)
+
 static const svn_auth_provider_t windows_server_authority_provider = {
     SVN_AUTH_CRED_SSL_SERVER_AUTHORITY,
     windows_ssl_server_trust_first_credentials,

Reply via email to