[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

svncpp crash in ssl_server_trust_file_save_credentials

From: Barry Scott <barry_at_barrys-emacs.org>
Date: 2004-01-17 20:25:59 CET

I'm testing SSL callbacks for the pysvn python extension and I'm seeing a
reproducible crash with 0.36.0.

Pysvn uses the svncpp library from rapidsvn patched to support 0.36.0.

I don't know if its the svncpp code or the svn code that is in
error here. Can an SSL auth export comment on where a fix needs
to be made please?

The crash occurs in svn_config_write_auth_data that is passed the
realmstring as NULL from ssl_server_trust_file_save_credentials
(ssl_server_providers.c).

This is because pb->realmstring is NULL in
ssl_server_trust_file_save_credential.

With the subversion client pb->realmstring will be setup by the code in
ssl_server_trust_file_first_credentials.

But the svncpp code has its own provider that implements the
first_credentials callback but not the save_credentials callback.

The code in svn_auth_save_credentials (libsvn_subr/auth.c) is designed
to hunt for a save_creditials callback. It loops over the providers,
and ends up calling ssl_server_trust_file_save_credentials has no
way of being given the realmstring and a crash occurs.

0.35.1 did not crash, it also did not save credential at all. I'm
guess that bug was fixed and exposed this new one.

The svncpp code that handles this is in src\svncpp\context.cpp in
the rapidsvn repository. I've applied this patch against the latest
version to support 0.36.0.

Barry

Index: context.cpp
===================================================================
--- context.cpp (revision 6998)
+++ context.cpp (working copy)
@@ -144,8 +144,9 @@
        *(svn_auth_provider_object_t **)apr_array_push (providers) =
          provider;

+ // plugged in 3 as the retry limit - what is a good limit?
        svn_client_get_ssl_client_cert_pw_prompt_provider (
- &provider, onSslClientCertPwPrompt, this, pool);
+ &provider, onSslClientCertPwPrompt, this, 3, pool);
        *(svn_auth_provider_object_t **)apr_array_push (providers) =
          provider;

@@ -285,12 +286,13 @@
                      void *baton,
                      const char *realm,
                      const char *username,
+ svn_boolean_t may_save,
                      apr_pool_t *pool)
      {
        Data * data;
        SVN_ERR (getData (baton, &data));

- if (!data->retrieveLogin (username, realm))
+ if (!data->retrieveLogin (username, realm, may_save != 0))
          return svn_error_create (SVN_ERR_CANCELLED, NULL, "");

        svn_auth_cred_simple_t* lcred = (svn_auth_cred_simple_t*)
@@ -316,6 +318,7 @@
                              const char *realm,
                              apr_uint32_t failures,
                              const svn_auth_ssl_server_cert_info_t *info,
+ svn_boolean_t may_save,
                              apr_pool_t *pool)
      {
        Data * data;
@@ -329,11 +332,12 @@
        trustData.validFrom = info->valid_from;
        trustData.validUntil = info->valid_until;
        trustData.issuerDName = info->issuer_dname;
+ trustData.maySave = may_save != 0;

        apr_uint32_t acceptedFailures;
        ContextListener::SslServerTrustAnswer answer =
          data->listener->contextSslServerTrustPrompt (
- trustData, acceptedFailures);
+ trustData, acceptedFailures );

        if(answer == ContextListener::DONT_ACCEPT)
          *cred = NULL;
@@ -345,7 +349,7 @@

          if (answer == ContextListener::ACCEPT_PERMANENTLY)
          {
- cred_->trust_permanently = 1;
+ cred_->may_save = 1;
            cred_->accepted_failures = acceptedFailures;
          }
          *cred = cred_;
@@ -390,13 +394,15 @@
      onSslClientCertPwPrompt (
        svn_auth_cred_ssl_client_cert_pw_t **cred,
        void *baton,
+ const char *realm,
+ svn_boolean_t may_save,
        apr_pool_t *pool)
      {
        Data * data;
        SVN_ERR (getData (baton, &data));

        std::string password ("");
- if (!data->listener->contextSslClientCertPwPrompt (password))
+ if (!data->listener->contextSslClientCertPwPrompt (password, realm,
may_save != 0))
          return svn_error_create (SVN_ERR_CANCELLED, NULL, "");

        svn_auth_cred_ssl_client_cert_pw_t *cred_ =
@@ -473,7 +479,8 @@
       */
      bool
      retrieveLogin (const char * username_,
- const char * realm)
+ const char * realm,
+ bool may_save)
      {
        bool ok;

@@ -485,7 +492,7 @@
        else
          username = username_;

- ok = listener->contextGetLogin (realm, username, password);
+ ok = listener->contextGetLogin (realm, username, password, may_save);

        return ok;
      }

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Sat Jan 17 20:26:40 2004

This is an archived mail posted to the Subversion Dev mailing list.