Author: cmpilato
Date: Tue May 21 18:08:07 2013
New Revision: 1484895

URL: http://svn.apache.org/r1484895
Log:
On the 'auth-notification' branch: Add the plumbing needed to transmit
notifications from the auth subsystem, and some code to exercise it.

* subversion/include/svn_auth.h
  (svn_auth_notify_action_t): New enum type for notification actions.
  (svn_auth_notify_func_t): New function type.
  (svn_auth_provider_t): Add 'provider_name' member to the end of this
    structure.
  (SVN_AUTH_PARAM_NOTIFY_FUNC, SVN_AUTH_PARAM_NOTIFY_BATON): New auth
    parameter names.

* subversion/include/svn_cmdline.h,
* subversion/libsvn_subr/cmdline.c
  (svn_cmdline_create_auth_baton2): New function.
  (svn_cmdline_create_auth_baton): Deprecate this one as a wrapper
    around the revised API.  ### Need to move this to deprecated.c

* subversion/libsvn_auth_gnome_keyring/gnome_keyring.c,
* subversion/libsvn_subr/simple_providers.c
  Add provider names to svn_auth_provider_t structures.

* subversion/libsvn_subr/auth.c
  (svn_auth_first_credentials, svn_auth_next_credentials,
   svn_auth_save_credentials): Look for notification function and
    baton in the auth baton parameter set, and notify about relevant
    actions.

* subversion/svn/svn.c
  (auth_notify): New implementation of the svn_auth_notify_func_t
    callback type.
  (main): New use svn_cmdline_create_auth_baton2(), passing an auth
    notification function iff the "SVN_AUTH_NOTIFY" environment variable
    is set.

Modified:
    subversion/branches/auth-notification/subversion/include/svn_auth.h
    subversion/branches/auth-notification/subversion/include/svn_cmdline.h
    
subversion/branches/auth-notification/subversion/libsvn_auth_gnome_keyring/gnome_keyring.c
    subversion/branches/auth-notification/subversion/libsvn_subr/auth.c
    subversion/branches/auth-notification/subversion/libsvn_subr/cmdline.c
    
subversion/branches/auth-notification/subversion/libsvn_subr/simple_providers.c
    subversion/branches/auth-notification/subversion/svn/svn.c

Modified: subversion/branches/auth-notification/subversion/include/svn_auth.h
URL: 
http://svn.apache.org/viewvc/subversion/branches/auth-notification/subversion/include/svn_auth.h?rev=1484895&r1=1484894&r2=1484895&view=diff
==============================================================================
--- subversion/branches/auth-notification/subversion/include/svn_auth.h 
(original)
+++ subversion/branches/auth-notification/subversion/include/svn_auth.h Tue May 
21 18:08:07 2013
@@ -89,6 +89,27 @@ typedef struct svn_auth_baton_t svn_auth
 /** The type of a Subversion authentication-iteration object */
 typedef struct svn_auth_iterstate_t svn_auth_iterstate_t;
 
+/** Notification actions for use with svn_auth_notify_func_t().
+ *
+ * @since New in 1.9.
+ */
+typedef enum svn_auth_notify_action_t
+  {
+    svn_auth_notify_creds_acquired = 0,
+    svn_auth_notify_creds_validated,
+    svn_auth_notify_creds_stored
+    
+  } svn_auth_notify_action_t;
+
+/** Callback type used for notifying about authentication-related
+ * events.
+ *
+ * @since New in 1.9.
+ */
+typedef svn_error_t *(*svn_auth_notify_func_t)(void *baton,
+                                               svn_auth_notify_action_t action,
+                                               const char *provider_name,
+                                               apr_pool_t *scratch_pool);
 
 /** The main authentication "provider" vtable. */
 typedef struct svn_auth_provider_t
@@ -150,6 +171,11 @@ typedef struct svn_auth_provider_t
                                     const char *realmstring,
                                     apr_pool_t *pool);
 
+  /** The name of the provider (for debugging, mostly).
+   * @since New in 1.9.
+   */
+  const char *provider_name;
+
 } svn_auth_provider_t;
 
 
@@ -648,6 +674,19 @@ svn_auth_get_parameter(svn_auth_baton_t 
  * ~/.subversion. */
 #define SVN_AUTH_PARAM_CONFIG_DIR SVN_AUTH_PARAM_PREFIX "config-dir"
 
+/** A notification function of type @c svn_auth_notify_func_t.
+ *
+ * @since New in 1.9.
+ */
+#define SVN_AUTH_PARAM_NOTIFY_FUNC SVN_AUTH_PARAM_PREFIX "notify-func"
+
+/** An implementation-specific closure used with the function
+ * specified by the @c SVN_AUTH_PARAM_NOTIFY_FUNC parameter.
+ *
+ * @since New in 1.9.
+ */
+#define SVN_AUTH_PARAM_NOTIFY_BATON SVN_AUTH_PARAM_PREFIX "notify-baton"
+
 /** Get an initial set of credentials.
  *
  * Ask @a auth_baton to set @a *credentials to a set of credentials

Modified: subversion/branches/auth-notification/subversion/include/svn_cmdline.h
URL: 
http://svn.apache.org/viewvc/subversion/branches/auth-notification/subversion/include/svn_cmdline.h?rev=1484895&r1=1484894&r2=1484895&view=diff
==============================================================================
--- subversion/branches/auth-notification/subversion/include/svn_cmdline.h 
(original)
+++ subversion/branches/auth-notification/subversion/include/svn_cmdline.h Tue 
May 21 18:08:07 2013
@@ -327,10 +327,35 @@ svn_cmdline_auth_plaintext_passphrase_pr
  * @a cancel_func and @a cancel_baton control the cancellation of the
  * prompting providers that are initialized.
  *
+ * @a notify_func and @a notify_baton are used to notify about
+ * authentication-related events.
+ *
  * Use @a pool for all allocations.
  *
+ * @since New in 1.9.
+ */
+svn_error_t *
+svn_cmdline_create_auth_baton2(svn_auth_baton_t **ab,
+                               svn_boolean_t non_interactive,
+                               const char *username,
+                               const char *password,
+                               const char *config_dir,
+                               svn_boolean_t no_auth_cache,
+                               svn_boolean_t trust_server_cert,
+                               svn_config_t *cfg,
+                               svn_auth_notify_func_t notify_func,
+                               void *notify_baton,
+                               svn_cancel_func_t cancel_func,
+                               void *cancel_baton,
+                               apr_pool_t *pool);
+
+/** Similar to svn_cmdline_create_auth_baton2(), but with @a
+ * notify_func and @a notify_baton always @c NULL.
+ *
  * @since New in 1.6.
+ * @deprecated Provided for backward compatibility with the 1.8 API.
  */
+SVN_DEPRECATED
 svn_error_t *
 svn_cmdline_create_auth_baton(svn_auth_baton_t **ab,
                               svn_boolean_t non_interactive,

Modified: 
subversion/branches/auth-notification/subversion/libsvn_auth_gnome_keyring/gnome_keyring.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/auth-notification/subversion/libsvn_auth_gnome_keyring/gnome_keyring.c?rev=1484895&r1=1484894&r2=1484895&view=diff
==============================================================================
--- 
subversion/branches/auth-notification/subversion/libsvn_auth_gnome_keyring/gnome_keyring.c
 (original)
+++ 
subversion/branches/auth-notification/subversion/libsvn_auth_gnome_keyring/gnome_keyring.c
 Tue May 21 18:08:07 2013
@@ -440,7 +440,8 @@ static const svn_auth_provider_t gnome_k
   SVN_AUTH_CRED_SIMPLE,
   simple_gnome_keyring_first_creds,
   NULL,
-  simple_gnome_keyring_save_creds
+  simple_gnome_keyring_save_creds,
+  "Gnome Keyring simple provider"
 };
 
 /* Public API */
@@ -499,7 +500,8 @@ static const svn_auth_provider_t gnome_k
   SVN_AUTH_CRED_SSL_CLIENT_CERT_PW,
   ssl_client_cert_pw_gnome_keyring_first_creds,
   NULL,
-  ssl_client_cert_pw_gnome_keyring_save_creds
+  ssl_client_cert_pw_gnome_keyring_save_creds,
+  "Gnome Keyring (SSL client cert passphrase)"
 };
 
 /* Public API */

Modified: subversion/branches/auth-notification/subversion/libsvn_subr/auth.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/auth-notification/subversion/libsvn_subr/auth.c?rev=1484895&r1=1484894&r2=1484895&view=diff
==============================================================================
--- subversion/branches/auth-notification/subversion/libsvn_subr/auth.c 
(original)
+++ subversion/branches/auth-notification/subversion/libsvn_subr/auth.c Tue May 
21 18:08:07 2013
@@ -213,7 +213,14 @@ svn_auth_first_credentials(void **creden
   svn_boolean_t got_first = FALSE;
   svn_auth_iterstate_t *iterstate;
   const char *cache_key;
+  svn_auth_notify_func_t auth_notify_func;
+  void *auth_notify_baton;
 
+  auth_notify_func = svn_hash_gets(auth_baton->parameters,
+                                   SVN_AUTH_PARAM_NOTIFY_FUNC);
+  auth_notify_baton = svn_hash_gets(auth_baton->parameters,
+                                    SVN_AUTH_PARAM_NOTIFY_BATON);
+                                            
   /* Get the appropriate table of providers for CRED_KIND. */
   table = svn_hash_gets(auth_baton->tables, cred_kind);
   if (! table)
@@ -227,6 +234,13 @@ svn_auth_first_credentials(void **creden
   if (creds)
     {
        got_first = FALSE;
+       if (auth_notify_func)
+         {
+           SVN_ERR(auth_notify_func(auth_notify_baton,
+                                    svn_auth_notify_creds_acquired,
+                                    "Auth Baton Cache",
+                                    pool));
+         }
     }
   else
     /* If not, find a provider that can give "first" credentials. */
@@ -245,6 +259,13 @@ svn_auth_first_credentials(void **creden
           if (creds != NULL)
             {
               got_first = TRUE;
+              if (auth_notify_func)
+                {
+                  SVN_ERR(auth_notify_func(auth_notify_baton,
+                                           svn_auth_notify_creds_acquired,
+                                           provider->vtable->provider_name,
+                                           pool));
+                }
               break;
             }
         }
@@ -286,6 +307,13 @@ svn_auth_next_credentials(void **credent
   svn_auth_provider_object_t *provider;
   provider_set_t *table = state->table;
   void *creds = NULL;
+  svn_auth_notify_func_t auth_notify_func;
+  void *auth_notify_baton;
+
+  auth_notify_func = svn_hash_gets(auth_baton->parameters,
+                                   SVN_AUTH_PARAM_NOTIFY_FUNC);
+  auth_notify_baton = svn_hash_gets(auth_baton->parameters,
+                                    SVN_AUTH_PARAM_NOTIFY_BATON);
 
   /* Continue traversing the table from where we left off. */
   for (/* no init */;
@@ -319,6 +347,13 @@ svn_auth_next_credentials(void **credent
         }
 
       state->got_first = FALSE;
+      if (auth_notify_func)
+        {
+          SVN_ERR(auth_notify_func(auth_notify_baton,
+                                   svn_auth_notify_creds_acquired,
+                                   provider->vtable->provider_name,
+                                   pool));
+        }
     }
 
   *credentials = creds;
@@ -337,6 +372,8 @@ svn_auth_save_credentials(svn_auth_iters
   const char *no_auth_cache;
   svn_auth_baton_t *auth_baton;
   void *creds;
+  svn_auth_notify_func_t auth_notify_func;
+  void *auth_notify_baton;
 
   if (! state || state->table->providers->nelts <= state->provider_idx)
     return SVN_NO_ERROR;
@@ -346,6 +383,18 @@ svn_auth_save_credentials(svn_auth_iters
   if (! creds)
     return SVN_NO_ERROR;
 
+  auth_notify_func = svn_hash_gets(auth_baton->parameters,
+                                   SVN_AUTH_PARAM_NOTIFY_FUNC);
+  auth_notify_baton = svn_hash_gets(auth_baton->parameters,
+                                    SVN_AUTH_PARAM_NOTIFY_BATON);
+
+  if (auth_notify_func)
+    {
+      SVN_ERR(auth_notify_func(auth_notify_baton,
+                               svn_auth_notify_creds_validated,
+                               NULL, pool));
+    }
+
   /* Do not save the creds if SVN_AUTH_PARAM_NO_AUTH_CACHE is set */
   no_auth_cache = svn_hash_gets(auth_baton->parameters,
                                 SVN_AUTH_PARAM_NO_AUTH_CACHE);
@@ -364,7 +413,15 @@ svn_auth_save_credentials(svn_auth_iters
                                                state->realmstring,
                                                pool));
   if (save_succeeded)
-    return SVN_NO_ERROR;
+    {
+      if (auth_notify_func)
+        {
+          SVN_ERR(auth_notify_func(auth_notify_baton,
+                                   svn_auth_notify_creds_stored,
+                                   provider->vtable->provider_name, pool));
+        }
+      return SVN_NO_ERROR;
+    }
 
   /* Otherwise, loop from the top of the list, asking every provider
      to attempt a save.  ### todo: someday optimize so we don't
@@ -382,6 +439,15 @@ svn_auth_save_credentials(svn_auth_iters
                  pool));
 
       if (save_succeeded)
+        {
+          if (auth_notify_func)
+            {
+              SVN_ERR(auth_notify_func(auth_notify_baton,
+                                       svn_auth_notify_creds_stored,
+                                       provider->vtable->provider_name,
+                                       pool));
+            }
+        }
         break;
     }
 

Modified: subversion/branches/auth-notification/subversion/libsvn_subr/cmdline.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/auth-notification/subversion/libsvn_subr/cmdline.c?rev=1484895&r1=1484894&r2=1484895&view=diff
==============================================================================
--- subversion/branches/auth-notification/subversion/libsvn_subr/cmdline.c 
(original)
+++ subversion/branches/auth-notification/subversion/libsvn_subr/cmdline.c Tue 
May 21 18:08:07 2013
@@ -454,17 +454,19 @@ ssl_trust_unknown_server_cert
 }
 
 svn_error_t *
-svn_cmdline_create_auth_baton(svn_auth_baton_t **ab,
-                              svn_boolean_t non_interactive,
-                              const char *auth_username,
-                              const char *auth_password,
-                              const char *config_dir,
-                              svn_boolean_t no_auth_cache,
-                              svn_boolean_t trust_server_cert,
-                              svn_config_t *cfg,
-                              svn_cancel_func_t cancel_func,
-                              void *cancel_baton,
-                              apr_pool_t *pool)
+svn_cmdline_create_auth_baton2(svn_auth_baton_t **ab,
+                               svn_boolean_t non_interactive,
+                               const char *auth_username,
+                               const char *auth_password,
+                               const char *config_dir,
+                               svn_boolean_t no_auth_cache,
+                               svn_boolean_t trust_server_cert,
+                               svn_config_t *cfg,
+                               svn_auth_notify_func_t notify_func,
+                               void *notify_baton,
+                               svn_cancel_func_t cancel_func,
+                               void *cancel_baton,
+                               apr_pool_t *pool)
 {
   svn_boolean_t store_password_val = TRUE;
   svn_boolean_t store_auth_creds_val = TRUE;
@@ -631,10 +633,40 @@ svn_cmdline_create_auth_baton(svn_auth_b
                          &svn_cmdline__auth_gnome_keyring_unlock_prompt);
 #endif /* SVN_HAVE_GNOME_KEYRING */
 
+  /* If we have a notification function, add it and its baton to the
+     auth baton parameter set. */
+  if (notify_func)
+    {
+      svn_auth_set_parameter(*ab, SVN_AUTH_PARAM_NOTIFY_FUNC, notify_func);
+      svn_auth_set_parameter(*ab, SVN_AUTH_PARAM_NOTIFY_BATON, notify_baton);
+    }
+
   return SVN_NO_ERROR;
 }
 
 svn_error_t *
+svn_cmdline_create_auth_baton(svn_auth_baton_t **ab,
+                              svn_boolean_t non_interactive,
+                              const char *auth_username,
+                              const char *auth_password,
+                              const char *config_dir,
+                              svn_boolean_t no_auth_cache,
+                              svn_boolean_t trust_server_cert,
+                              svn_config_t *cfg,
+                              svn_cancel_func_t cancel_func,
+                              void *cancel_baton,
+                              apr_pool_t *pool)
+{
+  return svn_cmdline_create_auth_baton2(ab, non_interactive,
+                                        auth_username, auth_password,
+                                        config_dir, no_auth_cache,
+                                        trust_server_cert, cfg,
+                                        NULL, NULL,
+                                        cancel_func, cancel_baton,
+                                        pool);
+}
+
+svn_error_t *
 svn_cmdline__getopt_init(apr_getopt_t **os,
                          int argc,
                          const char *argv[],

Modified: 
subversion/branches/auth-notification/subversion/libsvn_subr/simple_providers.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/auth-notification/subversion/libsvn_subr/simple_providers.c?rev=1484895&r1=1484894&r2=1484895&view=diff
==============================================================================
--- 
subversion/branches/auth-notification/subversion/libsvn_subr/simple_providers.c 
(original)
+++ 
subversion/branches/auth-notification/subversion/libsvn_subr/simple_providers.c 
Tue May 21 18:08:07 2013
@@ -515,7 +515,8 @@ static const svn_auth_provider_t simple_
   SVN_AUTH_CRED_SIMPLE,
   simple_first_creds,
   NULL,
-  simple_save_creds
+  simple_save_creds,
+  "Plaintext (simple)"
 };
 
 
@@ -709,6 +710,7 @@ static const svn_auth_provider_t simple_
   simple_prompt_first_creds,
   simple_prompt_next_creds,
   NULL,
+  "Plaintext (prompt)"
 };
 
 

Modified: subversion/branches/auth-notification/subversion/svn/svn.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/auth-notification/subversion/svn/svn.c?rev=1484895&r1=1484894&r2=1484895&view=diff
==============================================================================
--- subversion/branches/auth-notification/subversion/svn/svn.c (original)
+++ subversion/branches/auth-notification/subversion/svn/svn.c Tue May 21 
18:08:07 2013
@@ -1654,6 +1654,44 @@ svn_cl__check_cancel(void *baton)
     return SVN_NO_ERROR;
 }
 
+/* Auth notification callback (implements `svn_auth_notify_func_t'). */
+static svn_error_t *
+auth_notify(void *baton,
+            svn_auth_notify_action_t action,
+            const char *provider_name,
+            apr_pool_t *scratch_pool)
+{
+  if (! provider_name)
+    provider_name = "- unknown -";
+
+  switch (action)
+    {
+    case svn_auth_notify_creds_acquired:
+      return svn_cmdline_fprintf(stderr, scratch_pool,
+                                 _("Credentials acquired (%s)\n"),
+                                 provider_name);
+      /* not reached */
+
+    case svn_auth_notify_creds_validated:
+      return svn_cmdline_fputs(_("Credentials validated\n"),
+                               stderr, scratch_pool);
+      /* not reached */
+
+    case svn_auth_notify_creds_stored:
+      return svn_cmdline_fprintf(stderr, scratch_pool,
+                                 _("Credentials stored (%s)\n"),
+                                 provider_name);
+      /* not reached */
+
+    default:
+      break;
+    }
+
+  return SVN_NO_ERROR;
+}
+
+
+
 /* Add a --search argument to OPT_STATE.
  * These options start a new search pattern group. */
 static void
@@ -1735,6 +1773,7 @@ sub_main(int argc, const char *argv[], a
   svn_boolean_t reading_file_from_stdin = FALSE;
   apr_hash_t *changelists;
   apr_hash_t *cfg_hash;
+  svn_auth_notify_func_t auth_notify_func;
 
   received_opts = apr_array_make(pool, SVN_OPT_MAX_OPTIONS, sizeof(int));
 
@@ -2814,17 +2853,24 @@ sub_main(int argc, const char *argv[], a
 #endif
 
   /* Set up Authentication stuff. */
-  SVN_INT_ERR(svn_cmdline_create_auth_baton(&ab,
-                                            opt_state.non_interactive,
-                                            opt_state.auth_username,
-                                            opt_state.auth_password,
-                                            opt_state.config_dir,
-                                            opt_state.no_auth_cache,
-                                            opt_state.trust_server_cert,
-                                            cfg_config,
-                                            ctx->cancel_func,
-                                            ctx->cancel_baton,
-                                            pool));
+  auth_notify_func = NULL;
+  if (getenv("SVN_AUTH_NOTIFY"))
+    {
+      auth_notify_func = auth_notify;
+    }
+  SVN_INT_ERR(svn_cmdline_create_auth_baton2(&ab,
+                                             opt_state.non_interactive,
+                                             opt_state.auth_username,
+                                             opt_state.auth_password,
+                                             opt_state.config_dir,
+                                             opt_state.no_auth_cache,
+                                             opt_state.trust_server_cert,
+                                             cfg_config,
+                                             auth_notify_func,
+                                             NULL /* auth_notify_baton */,
+                                             ctx->cancel_func,
+                                             ctx->cancel_baton,
+                                             pool));
 
   ctx->auth_baton = ab;
 


Reply via email to