You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by st...@apache.org on 2012/02/07 20:10:42 UTC

svn commit: r1241554 - in /subversion/trunk: subversion/bindings/swig/ subversion/bindings/swig/perl/libsvn_swig_perl/ subversion/bindings/swig/perl/native/t/ subversion/bindings/swig/python/libsvn_swig_py/ subversion/bindings/swig/python/tests/ subver...

Author: stsp
Date: Tue Feb  7 19:10:41 2012
New Revision: 1241554

URL: http://svn.apache.org/viewvc?rev=1241554&view=rev
Log:
Allow setting the SVN_AUTH_PARAM_GNOME_KEYRING_UNLOCK_PROMPT_FUNC
authentication parameter from the perl, python and ruby bindings.

This parameter cannot be set using the regular svn_auth_set_parameter
function, since the function from perl/python/ruby space must be wrapped
in a C function to allow it to be called. For this reason, a new
function, svn_auth_set_gnome_keyring_unlock_prompt_func, is introduced
(in the bindings only).

[in subversion/bindings/swig]

* core.i
  (svn_auth_set_gnome_keyring_unlock_prompt_func): Add function and
  setup corresponding authprompt_callback_typemap.

* perl/libsvn_swig_perl/swigutil_pl.c,
  perl/libsvn_swig_perl/swigutil_pl.h
  (svn_swig_pl_thunk_gnome_keyring_unlock_prompt): Add function (called
  by authprompt_callback_typemap)

* python/libsvn_swig_py/swigutil_py.c
  python/libsvn_swig_py/swigutil_py.h
  (svn_swig_py_auth_gnome_keyring_unlock_prompt_func): Add function
  (called by authprompt_callback_typemap)

* ruby/libsvn_swig_ruby/swigutil_rb.c,
  ruby/libsvn_swig_ruby/swigutil_rb.h
  (svn_swig_rb_auth_gnome_keyring_unlock_prompt_func): Add function
  (called by authprompt_callback_typemap)

* perl/native/t/3client.t,
  python/tests/client.py
  Add test for svn_auth_set_gnome_keyring_unlock_prompt_func.

[in tools/examples]

* get-location-segments.py,
  info.rb
  Use the new svn_auth_set_gnome_keyring_unlock_prompt_func function.

Patch by: Matthijs Kooijman <ma...@stdin.nl>

Modified:
    subversion/trunk/subversion/bindings/swig/core.i
    subversion/trunk/subversion/bindings/swig/perl/libsvn_swig_perl/swigutil_pl.c
    subversion/trunk/subversion/bindings/swig/perl/libsvn_swig_perl/swigutil_pl.h
    subversion/trunk/subversion/bindings/swig/perl/native/t/3client.t
    subversion/trunk/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c
    subversion/trunk/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.h
    subversion/trunk/subversion/bindings/swig/python/tests/client.py
    subversion/trunk/subversion/bindings/swig/ruby/libsvn_swig_ruby/swigutil_rb.c
    subversion/trunk/subversion/bindings/swig/ruby/libsvn_swig_ruby/swigutil_rb.h
    subversion/trunk/tools/examples/get-location-segments.py
    subversion/trunk/tools/examples/info.rb

Modified: subversion/trunk/subversion/bindings/swig/core.i
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/swig/core.i?rev=1241554&r1=1241553&r2=1241554&view=diff
==============================================================================
--- subversion/trunk/subversion/bindings/swig/core.i (original)
+++ subversion/trunk/subversion/bindings/swig/core.i Tue Feb  7 19:10:41 2012
@@ -699,6 +699,34 @@ svn_swig_pl_set_current_pool (apr_pool_t
 %authprompt_callback_typemap(ssl_client_cert)
 %authprompt_callback_typemap(ssl_client_cert_pw)
 
+%{
+#ifdef SVN_AUTH_PARAM_GNOME_KEYRING_UNLOCK_PROMPT_FUNC
+/* Helper function to set the gnome-keyring unlock prompt function. This
+ * C function accepts an auth baton, a function and a prompt baton, but
+ * the below callback_typemap uses both the function and the prompt
+ * baton, so the resulting binding has just two arguments: The auth
+ * baton and the prompt function.
+ * The prompt function should again have two arguments: The keyring name
+ * (string) and a pool (except for the ruby version, which doesn't have
+ * the pool argument). It should return the entered password (string).
+ * This binding generated for this function generates a reference to the
+ * prompt function that was passed into this. The caller should store
+ * that reference somewhere, to prevent the function from being garbage
+ * collected...
+ */
+static void svn_auth_set_gnome_keyring_unlock_prompt_func(svn_auth_baton_t *ab,
+                                                          svn_auth_gnome_keyring_unlock_prompt_func_t prompt_func,
+                                                          void *prompt_baton) {
+    svn_auth_set_parameter(ab, SVN_AUTH_PARAM_GNOME_KEYRING_UNLOCK_PROMPT_FUNC,
+                           prompt_func);
+    svn_auth_set_parameter(ab, SVN_AUTH_PARAM_GNOME_KEYRING_UNLOCK_PROMPT_BATON,
+                           prompt_baton);
+}
+#endif
+%}
+
+%authprompt_callback_typemap(gnome_keyring_unlock)
+
 /* -----------------------------------------------------------------------
  * For all the various functions that set a callback baton create a reference
  * for the baton (which in this case is an SV pointing to the callback)
@@ -764,6 +792,12 @@ svn_swig_pl_set_current_pool (apr_pool_t
 %include svn_pools_h.swg
 %include svn_version_h.swg
 
+/* This is the function defined above */
+void svn_auth_set_gnome_keyring_unlock_prompt_func(svn_auth_baton_t *ab,
+                                                   svn_auth_gnome_keyring_unlock_prompt_func_t prompt_func,
+                                                   void *prompt_baton);
+
+
 /* The constant SVN_PROP_REVISION_ALL_PROPS is a C fragment, not a single
    data value, so the SWIG parser will raise a 305 warning if we don't
    suppress it. */

Modified: subversion/trunk/subversion/bindings/swig/perl/libsvn_swig_perl/swigutil_pl.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/swig/perl/libsvn_swig_perl/swigutil_pl.c?rev=1241554&r1=1241553&r2=1241554&view=diff
==============================================================================
--- subversion/trunk/subversion/bindings/swig/perl/libsvn_swig_perl/swigutil_pl.c (original)
+++ subversion/trunk/subversion/bindings/swig/perl/libsvn_swig_perl/swigutil_pl.c Tue Feb  7 19:10:41 2012
@@ -984,6 +984,34 @@ svn_error_t *svn_ra_make_callbacks(svn_r
     return SVN_NO_ERROR;
 }
 
+svn_error_t *svn_swig_pl_thunk_gnome_keyring_unlock_prompt(char **keyring_password,
+                                                           const char *keyring_name,
+                                                           void *baton,
+                                                           apr_pool_t *pool)
+{
+    SV *result;
+    STRLEN len;
+    /* The baton is the actual prompt function passed from perl, so we
+     * call that one and process the result. */
+    svn_swig_pl_callback_thunk(CALL_SV,
+                               baton, &result,
+                               "sS", keyring_name,
+                               pool, POOLINFO);
+    if (!SvOK(result) || result == &PL_sv_undef) {
+        *keyring_password = NULL;
+    }
+    else if (SvPOK(result)) {
+        *keyring_password = apr_pstrdup(pool, SvPV(result, len));
+    }
+    else {
+        SvREFCNT_dec(result);
+        croak("not a string");
+    }
+
+    SvREFCNT_dec(result);
+    return SVN_NO_ERROR;
+}
+
 svn_error_t *svn_swig_pl_thunk_simple_prompt(svn_auth_cred_simple_t **cred,
                                              void *baton,
                                              const char *realm,

Modified: subversion/trunk/subversion/bindings/swig/perl/libsvn_swig_perl/swigutil_pl.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/swig/perl/libsvn_swig_perl/swigutil_pl.h?rev=1241554&r1=1241553&r2=1241554&view=diff
==============================================================================
--- subversion/trunk/subversion/bindings/swig/perl/libsvn_swig_perl/swigutil_pl.h (original)
+++ subversion/trunk/subversion/bindings/swig/perl/libsvn_swig_perl/swigutil_pl.h Tue Feb  7 19:10:41 2012
@@ -144,6 +144,11 @@ svn_error_t *svn_ra_make_callbacks(svn_r
 				   SV *perl_callbacks,
 				   apr_pool_t *pool);
 
+/* thunked gnome_keyring_unlock_prompt callback function */
+svn_error_t *svn_swig_pl_thunk_gnome_keyring_unlock_prompt(char **keyring_password,
+                                                           const char *keyring_name,
+                                                           void *baton,
+                                                           apr_pool_t *pool);
 /* thunked simple_prompt callback function */
 svn_error_t *svn_swig_pl_thunk_simple_prompt(svn_auth_cred_simple_t **cred,
                                              void *baton,

Modified: subversion/trunk/subversion/bindings/swig/perl/native/t/3client.t
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/swig/perl/native/t/3client.t?rev=1241554&r1=1241553&r2=1241554&view=diff
==============================================================================
--- subversion/trunk/subversion/bindings/swig/perl/native/t/3client.t (original)
+++ subversion/trunk/subversion/bindings/swig/perl/native/t/3client.t Tue Feb  7 19:10:41 2012
@@ -20,7 +20,7 @@
 #
 #
 
-use Test::More tests => 119;
+use Test::More tests => 120;
 use strict;
 
 # shut up about variables that are only used once.
@@ -477,6 +477,23 @@ foreach my $p (@providers) {
 }
 ok($ok, 'svn_auth_get_platform_specific_client_providers returns _p_svn_auth_provider_object_t\'s');
 
+# Test setting gnome_keyring prompt function. This just sets the proper
+# attributes in the auth baton and checks the return value (which should
+# be a reference to the passed function reference). This does not
+# actually try the prompt, since that would require setting up a
+# gnome-keyring-daemon...
+sub gnome_keyring_unlock_prompt {
+    my $keyring_name = shift;
+    my $pool = shift;
+
+    'test';
+}
+
+my $callback = \&gnome_keyring_unlock_prompt;
+my $result = SVN::Core::auth_set_gnome_keyring_unlock_prompt_func(
+              $ctx->auth(), $callback);
+is(${$result}, $callback, 'auth_set_gnome_keyring_unlock_prompt_func result equals paramter');
+
 END {
 diag('cleanup');
 rmtree($testpath);

Modified: subversion/trunk/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c?rev=1241554&r1=1241553&r2=1241554&view=diff
==============================================================================
--- subversion/trunk/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c (original)
+++ subversion/trunk/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c Tue Feb  7 19:10:41 2012
@@ -2804,6 +2804,41 @@ svn_error_t *svn_swig_py_changelist_rece
 }
 
 svn_error_t *
+svn_swig_py_auth_gnome_keyring_unlock_prompt_func(char **keyring_passwd,
+                                                  const char *keyring_name,
+                                                  void *baton,
+                                                  apr_pool_t *pool)
+{
+  /* The baton is the actual prompt function passed from python */
+  PyObject *function = baton;
+  PyObject *result;
+  svn_error_t *err = SVN_NO_ERROR;
+  *keyring_passwd = NULL;
+
+  if ((function == NULL) || (function == Py_None))
+    return SVN_NO_ERROR;
+
+  svn_swig_py_acquire_py_lock();
+
+  if ((result = PyObject_CallFunction(function,
+                                      (char *)"sO&",
+                                      keyring_name,
+                                      make_ob_pool, pool)) == NULL)
+    {
+      err = callback_exception_error();
+    }
+  else
+    {
+      *keyring_passwd = make_string_from_ob(result, pool);
+      Py_DECREF(result);
+    }
+
+  svn_swig_py_release_py_lock();
+  return err;
+}
+
+
+svn_error_t *
 svn_swig_py_auth_simple_prompt_func(svn_auth_cred_simple_t **cred,
                                     void *baton,
                                     const char *realm,

Modified: subversion/trunk/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.h?rev=1241554&r1=1241553&r2=1241554&view=diff
==============================================================================
--- subversion/trunk/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.h (original)
+++ subversion/trunk/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.h Tue Feb  7 19:10:41 2012
@@ -423,6 +423,13 @@ svn_error_t *svn_swig_py_changelist_rece
 
 /* auth provider callbacks */
 SVN_SWIG_SWIGUTIL_EXPORT
+svn_error_t * svn_swig_py_auth_gnome_keyring_unlock_prompt_func(
+        char **keyring_passwd,
+        const char *keyring_name,
+        void *baton,
+        apr_pool_t *pool);
+
+SVN_SWIG_SWIGUTIL_EXPORT
 svn_error_t *svn_swig_py_auth_simple_prompt_func(
     svn_auth_cred_simple_t **cred,
     void *baton,

Modified: subversion/trunk/subversion/bindings/swig/python/tests/client.py
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/swig/python/tests/client.py?rev=1241554&r1=1241553&r2=1241554&view=diff
==============================================================================
--- subversion/trunk/subversion/bindings/swig/python/tests/client.py (original)
+++ subversion/trunk/subversion/bindings/swig/python/tests/client.py Tue Feb  7 19:10:41 2012
@@ -379,6 +379,17 @@ class SubversionClientTestCase(unittest.
     # Not much more we can test in this minimal environment.
     self.assert_(isinstance(providers, list))
 
+  def testGnomeKeyring(self):
+    # This tests setting the gnome-keyring unlock prompt function as an
+    # auth baton parameter. It doesn't actually call gnome-keyring
+    # stuff, since that would require having a gnome-keyring running. We
+    # just test if this doesn't error out, there's not even a return
+    # value to test.
+    def prompt_func(realm_string, pool):
+      return "Foo"
+
+    core.svn_auth_set_gnome_keyring_unlock_prompt_func(self.client_ctx.auth_baton, prompt_func)
+
 def suite():
     return unittest.defaultTestLoader.loadTestsFromTestCase(
       SubversionClientTestCase)

Modified: subversion/trunk/subversion/bindings/swig/ruby/libsvn_swig_ruby/swigutil_rb.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/swig/ruby/libsvn_swig_ruby/swigutil_rb.c?rev=1241554&r1=1241553&r2=1241554&view=diff
==============================================================================
--- subversion/trunk/subversion/bindings/swig/ruby/libsvn_swig_ruby/swigutil_rb.c (original)
+++ subversion/trunk/subversion/bindings/swig/ruby/libsvn_swig_ruby/swigutil_rb.c Tue Feb  7 19:10:41 2012
@@ -2963,6 +2963,41 @@ svn_swig_rb_auth_simple_prompt_func(svn_
 }
 
 svn_error_t *
+svn_swig_rb_auth_gnome_keyring_unlock_prompt_func(char **keyring_passwd,
+                                                  const char *keyring_name,
+                                                  void *baton,
+                                                  apr_pool_t *pool)
+{
+  svn_error_t *err = SVN_NO_ERROR;
+  VALUE proc, rb_pool;
+  *keyring_passwd = NULL;
+
+  svn_swig_rb_from_baton((VALUE)baton, &proc, &rb_pool);
+
+  if (!NIL_P(proc)) {
+    char error_message[] =
+      "svn_auth_gnome_keyring_unlock_prompt_func_t should"
+      "return a string, not '%s'.";
+
+    callback_baton_t cbb;
+    VALUE result;
+
+    cbb.receiver = proc;
+    cbb.message = id_call;
+    cbb.args = rb_ary_new3(1, c2r_string2(keyring_name));
+    result = invoke_callback_handle_error((VALUE)(&cbb), rb_pool, &err);
+
+    if (!NIL_P(result)) {
+      if (!RTEST(rb_obj_is_kind_of(result, rb_cString)))
+        rb_raise(rb_eTypeError, error_message, r2c_inspect(result));
+      *keyring_passwd = (char *)r2c_string(result, NULL, pool);
+    }
+  }
+
+  return err;
+}
+
+svn_error_t *
 svn_swig_rb_auth_username_prompt_func(svn_auth_cred_username_t **cred,
                                       void *baton,
                                       const char *realm,

Modified: subversion/trunk/subversion/bindings/swig/ruby/libsvn_swig_ruby/swigutil_rb.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/swig/ruby/libsvn_swig_ruby/swigutil_rb.h?rev=1241554&r1=1241553&r2=1241554&view=diff
==============================================================================
--- subversion/trunk/subversion/bindings/swig/ruby/libsvn_swig_ruby/swigutil_rb.h (original)
+++ subversion/trunk/subversion/bindings/swig/ruby/libsvn_swig_ruby/swigutil_rb.h Tue Feb  7 19:10:41 2012
@@ -380,6 +380,13 @@ svn_error_t *svn_swig_rb_wc_relocation_v
 
 /* auth provider callbacks */
 SVN_RB_SWIG_SWIGUTIL_EXPORT
+svn_error_t * svn_swig_rb_auth_gnome_keyring_unlock_prompt_func(
+    char **keyring_passwd,
+    const char *keyring_name,
+    void *baton,
+    apr_pool_t *pool);
+
+SVN_RB_SWIG_SWIGUTIL_EXPORT
 svn_error_t *svn_swig_rb_auth_simple_prompt_func(
     svn_auth_cred_simple_t **cred,
     void *baton,

Modified: subversion/trunk/tools/examples/get-location-segments.py
URL: http://svn.apache.org/viewvc/subversion/trunk/tools/examples/get-location-segments.py?rev=1241554&r1=1241553&r2=1241554&view=diff
==============================================================================
--- subversion/trunk/tools/examples/get-location-segments.py (original)
+++ subversion/trunk/tools/examples/get-location-segments.py Tue Feb  7 19:10:41 2012
@@ -105,6 +105,9 @@ def prompt_func_simple_prompt(realm, use
   simple_cred.may_save = False
   return simple_cred
 
+def prompt_func_gnome_keyring_prompt(keyring, pool):
+  return getpass.getpass(prompt="Password for '%s' GNOME keyring: " % keyring)
+
 def main():
   try:
     url, peg_revision, start_revision, end_revision = parse_args(sys.argv[1:])
@@ -145,6 +148,9 @@ ERROR: %s
   ctx.auth_baton = core.svn_auth_open(providers)
   ctx.config = core.svn_config_get_config(None)
 
+  if hasattr(core, 'svn_auth_set_gnome_keyring_unlock_prompt_func'):
+    core.svn_auth_set_gnome_keyring_unlock_prompt_func(ctx.auth_baton, prompt_func_gnome_keyring_prompt)
+
   ra_callbacks = ra.callbacks_t()
   ra_callbacks.auth_baton = ctx.auth_baton
   ra_session = ra.open(url, ra_callbacks, None, ctx.config)

Modified: subversion/trunk/tools/examples/info.rb
URL: http://svn.apache.org/viewvc/subversion/trunk/tools/examples/info.rb?rev=1241554&r1=1241553&r2=1241554&view=diff
==============================================================================
--- subversion/trunk/tools/examples/info.rb (original)
+++ subversion/trunk/tools/examples/info.rb Tue Feb  7 19:10:41 2012
@@ -26,6 +26,7 @@
 #
 
 require "svn/core"
+require "svn/ext/core"
 require "svn/client"
 require "svn/wc"
 require "svn/repos"
@@ -45,6 +46,12 @@ simple_prompt = Proc.new do
   result.password = STDIN.gets.strip
 end
 
+gnome_keyring_prompt = Proc.new do
+  |keyring_name|
+
+  print "Password for '#{keyring_name}' GNOME keyring: "
+  STDIN.gets.strip
+end
 
 if ARGV.length != 1
   puts "Usage: info.rb URL[@REV]"
@@ -58,6 +65,12 @@ else
   ctx.add_ssl_client_cert_file_provider
   ctx.add_ssl_client_cert_pw_file_provider
 
+  # Allow asking for the gnome keyring password, in case the keyring is
+  # locked.
+  if Svn::Ext::Core.respond_to?(:svn_auth_set_gnome_keyring_unlock_prompt_func)
+    Svn::Ext::Core::svn_auth_set_gnome_keyring_unlock_prompt_func(ctx.auth_baton, gnome_keyring_prompt)
+  end
+
   repos_uri, revision = ARGV[0].split("@", 2)
   if revision
     revision = Integer(revision)