You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@subversion.apache.org by Stefan Sperling <st...@elego.de> on 2016/10/21 10:52:09 UTC

Re: subversion issue: ignore server invaild certificate in linux

On Fri, Oct 21, 2016 at 06:08:45PM +0800, yuan lixin wrote:
> Dear stefan:
> 
> At first, my code is using the "libsvncpp", that has its own providers, and it can run normal in windows.
> second, i used the svns's code to implement of downloading and uploading, not the svn cmd line. the "--trust-server-cert\u201d and \u201c\u201d--trust-server-cert-failures\u201d is the layer of svn.exe\uff0cbut refer to the two parameter , i trace  the svn code :
> 
> code file:"\src-trunk\subversion\libsvn_subr\ssl_server_trust_providers.c"
> >        ...
> >        *failures = 0;   //wj  add
> >         /* If all failures are cleared now, we return the creds */
> >         if (! *failures)
> >         {
> >               svn_auth_cred_ssl_server_trust_t *creds =
> >                 apr_pcalloc(pool, sizeof(*creds));
> >                   creds->may_save = FALSE; /* No need to save it again... */
> >               *credentials = creds;
> > 
> >         }
> or 
> >     typedef svn_error_t *(*svn_auth_ssl_server_trust_prompt_func_t)(
> >             svn_auth_cred_ssl_server_trust_t **cred,
> >             void *baton,
> >             const char *realm,
> >             apr_uint32_t *failures,
> >             const svn_auth_ssl_server_cert_info_t *cert_info,
> >             svn_boolean_t may_save,
> >             apr_pool_t *pool);
> 
> but my leader ask me to do not change the svn's code, so it a problem for me. would you help me for another adear.
> Thank you
> --woodsp
> 
> 

I am not suggesting that you use svn.exe. I am suggesting that you use
similar code in your application as svn.exe is using, and use SVN's API.

Implement your own provieder with an svn_auth_ssl_server_trust_prompt_func_t
which just sets *failures to 0. Then register that provider when you
init the auth subsystem.

It sounds like libsvncpp is managing the auth subssytem for you.
So you may need to modify libsvncpp for this.

Another and better solution might be using a valid SSL certificate ;-)

Re: subversion issue: ignore server invaild certificate in linux

Posted by Branko Čibej <br...@apache.org>.
On 21.10.2016 13:34, yuan lixin wrote:
> but  in the  interface "svn_auth_ssl_server_trust_prompt_func_t",  <br/>the actual parameter is "failures", not "*failures". so it can not change <br/>the svn's failures in linux, then can not ignore certificate.

The svn_auth_ssl_server_trust_prompt_func_t function must return an
svn_auth_cred_ssl_server_trust_t structure, which has a member
accepted_failures; set that to the value of the incoming failures
parameter and may_save to FALSE and you're done. See
svn_cmdline_auth_ssl_server_trust_prompt() in
subversion/libsvn_subr/prompt.c.

This is all documented in the headers, see include/svn_auth.h.

> could you look at my code for a solution.

You've already been told that changing a public API is not acceptable.

-- Brane

> At 2016-10-21 18:52:09, "Stefan Sperling" <st...@elego.de> wrote:
>> On Fri, Oct 21, 2016 at 06:08:45PM +0800, yuan lixin wrote:
>>> Dear stefan:
>>>
>>> At first, my code is using the "libsvncpp", that has its own providers, and it can run normal in windows.
>>> second, i used the svns's code to implement of downloading and uploading, not the svn cmd line. the "--trust-server-cert\u201d and \u201c\u201d--trust-server-cert-failures\u201d is the layer of svn.exe\uff0cbut refer to the two parameter , i trace  the svn code :
>>>
>>> code file:"\src-trunk\subversion\libsvn_subr\ssl_server_trust_providers.c"
>>>>        ...
>>>>        *failures = 0;   //wj  add
>>>>         /* If all failures are cleared now, we return the creds */
>>>>         if (! *failures)
>>>>         {
>>>>               svn_auth_cred_ssl_server_trust_t *creds =
>>>>                 apr_pcalloc(pool, sizeof(*creds));
>>>>                   creds->may_save = FALSE; /* No need to save it again... */
>>>>               *credentials = creds;
>>>>
>>>>         }
>>> or 
>>>>     typedef svn_error_t *(*svn_auth_ssl_server_trust_prompt_func_t)(
>>>>             svn_auth_cred_ssl_server_trust_t **cred,
>>>>             void *baton,
>>>>             const char *realm,
>>>>             apr_uint32_t *failures,
>>>>             const svn_auth_ssl_server_cert_info_t *cert_info,
>>>>             svn_boolean_t may_save,
>>>>             apr_pool_t *pool);
>>> but my leader ask me to do not change the svn's code, so it a problem for me. would you help me for another adear.
>>> Thank you
>>> --woodsp
>>>
>>>
>> I am not suggesting that you use svn.exe. I am suggesting that you use
>> similar code in your application as svn.exe is using, and use SVN's API.
>>
>> Implement your own provieder with an svn_auth_ssl_server_trust_prompt_func_t
>> which just sets *failures to 0. Then register that provider when you
>> init the auth subsystem.
>>
>> It sounds like libsvncpp is managing the auth subssytem for you.
>> So you may need to modify libsvncpp for this.
>>
>> Another and better solution might be using a valid SSL certificate ;-)



Re:Re: subversion issue: ignore server invaild certificate in linux

Posted by yuan lixin <wo...@126.com>.
but  in the  interface "svn_auth_ssl_server_trust_prompt_func_t",  <br/>the actual parameter is "failures", not "*failures". so it can not change <br/>the svn's failures in linux, then can not ignore certificate.<br/>could you look at my code for a solution.<br/><br/>Thank you<br/>--woodsp
At 2016-10-21 18:52:09, "Stefan Sperling" <st...@elego.de> wrote:
>On Fri, Oct 21, 2016 at 06:08:45PM +0800, yuan lixin wrote:
>> Dear stefan:
>> 
>> At first, my code is using the "libsvncpp", that has its own providers, and it can run normal in windows.
>> second, i used the svns's code to implement of downloading and uploading, not the svn cmd line. the "--trust-server-cert” and “”--trust-server-cert-failures” is the layer of svn.exe,but refer to the two parameter , i trace  the svn code :
>> 
>> code file:"\src-trunk\subversion\libsvn_subr\ssl_server_trust_providers.c"
>> >        ...
>> >        *failures = 0;   //wj  add
>> >         /* If all failures are cleared now, we return the creds */
>> >         if (! *failures)
>> >         {
>> >               svn_auth_cred_ssl_server_trust_t *creds =
>> >                 apr_pcalloc(pool, sizeof(*creds));
>> >                   creds->may_save = FALSE; /* No need to save it again... */
>> >               *credentials = creds;
>> > 
>> >         }
>> or 
>> >     typedef svn_error_t *(*svn_auth_ssl_server_trust_prompt_func_t)(
>> >             svn_auth_cred_ssl_server_trust_t **cred,
>> >             void *baton,
>> >             const char *realm,
>> >             apr_uint32_t *failures,
>> >             const svn_auth_ssl_server_cert_info_t *cert_info,
>> >             svn_boolean_t may_save,
>> >             apr_pool_t *pool);
>> 
>> but my leader ask me to do not change the svn's code, so it a problem for me. would you help me for another adear.
>> Thank you
>> --woodsp
>> 
>> 
>
>I am not suggesting that you use svn.exe. I am suggesting that you use
>similar code in your application as svn.exe is using, and use SVN's API.
>
>Implement your own provieder with an svn_auth_ssl_server_trust_prompt_func_t
>which just sets *failures to 0. Then register that provider when you
>init the auth subsystem.
>
>It sounds like libsvncpp is managing the auth subssytem for you.
>So you may need to modify libsvncpp for this.
>
>Another and better solution might be using a valid SSL certificate ;-)

Re:Re:subversion issue: ignore server invaild certificate in linux

Posted by yuan lixin <wo...@126.com>.
At 2016-10-22 21:29:59, "yuan lixin" <wo...@126.com> wrote:

The function "onSslServerTrustPrompt"  is part of libsvncpp,
i put a few of it,the whole code is below:


/**
     * @see svn_auth_ssl_server_trust_prompt_func_t
     */
    static svn_error_t *
    onSslServerTrustPrompt(svn_auth_cred_ssl_server_trust_t **cred,
                           void *baton,
                           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 = NULL;
      SVN_ERR(getData(baton, &data));

      ContextListener::SslServerTrustData trustData(failures);
      if (realm != NULL)
        trustData.realm = realm;
      trustData.hostname = info->hostname;
      trustData.fingerprint = info->fingerprint;
      trustData.validFrom = info->valid_from;
      trustData.validUntil = info->valid_until;
      trustData.issuerDName = info->issuer_dname;
      trustData.maySave = may_save != 0;

      if (data->listener == 0)
        return svn_error_create(SVN_ERR_CANCELLED, NULL,
                                "invalid listener");
      apr_uint32_t acceptedFailures;
      ContextListener::SslServerTrustAnswer answer =
        data->listener->contextSslServerTrustPrompt(
          trustData, acceptedFailures);

      if (answer == ContextListener::DONT_ACCEPT)
        *cred = NULL;
      else
      {
        svn_auth_cred_ssl_server_trust_t *cred_ =
          (svn_auth_cred_ssl_server_trust_t*)
          apr_palloc(pool, sizeof(svn_auth_cred_ssl_server_trust_t));

        if (answer == ContextListener::ACCEPT_PERMANENTLY)
        {
          cred_->may_save = 1;
          cred_->accepted_failures = acceptedFailures;
        }
        *cred = cred_;
      }

      return SVN_NO_ERROR;

    }







At 2016-10-22 20:40:11, "Daniel Shahaf" <da...@apache.org> wrote:
>yuan lixin wrote on Sat, Oct 22, 2016 at 20:26:42 +0800:
>>       static svn_error_t *
>>       onSslServerTrustPrompt(svn_auth_cred_ssl_server_trust_t **cred,
>>                            void *baton,
>>                            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)
>>      {
>>           svn_auth_cred_ssl_server_trust_t *cred_ =
>>                  (svn_auth_cred_ssl_server_trust_t*)
>>                  apr_palloc(pool, sizeof(svn_auth_cred_ssl_server_trust_t));
>
>Is this forward compatible?  svn_auth_cred_ssl_server_trust_t doesn't
>have a constructor function, so if the above code is permissible, then
>we're not allowed to extend that struct type in minor releases.
>
>>           cred_->may_save = 1;
>>           cred_->accepted_failures = acceptedFailures;
>
>You may want to do (acceptedFailures & failures) so once you switch to
>a valid certificate, the cache will not record more "accepted
>failures" than are required.



>>           cred_->may_save = 1;
>>           cred_->accepted_failures = acceptedFailures;
>
>You may want to do (acceptedFailures & failures) so once you switch to
>a valid certificate, the cache will not record more "accepted
>failures" than are required.



Your  idea is exact. the orignal code is:
https://github.com/nydehi/fluorescence/blob/master/src/updater/svncpp/context.cpp
https://github.com/nydehi/fluorescence/blob/master/src/updater/svn.cpp 


 

Re: RE:subversion issue: ignore server invaild certificate in linux

Posted by Daniel Shahaf <da...@apache.org>.
yuan lixin wrote on Sat, Oct 22, 2016 at 20:26:42 +0800:
>       static svn_error_t *
>       onSslServerTrustPrompt(svn_auth_cred_ssl_server_trust_t **cred,
>                            void *baton,
>                            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)
>      {
>           svn_auth_cred_ssl_server_trust_t *cred_ =
>                  (svn_auth_cred_ssl_server_trust_t*)
>                  apr_palloc(pool, sizeof(svn_auth_cred_ssl_server_trust_t));

Is this forward compatible?  svn_auth_cred_ssl_server_trust_t doesn't
have a constructor function, so if the above code is permissible, then
we're not allowed to extend that struct type in minor releases.

>           cred_->may_save = 1;
>           cred_->accepted_failures = acceptedFailures;

You may want to do (acceptedFailures & failures) so once you switch to
a valid certificate, the cache will not record more "accepted
failures" than are required.

Re:RE:subversion issue: ignore server invaild certificate in linux

Posted by yuan lixin <wo...@126.com>.
Thank you all. the issue of ignoring server invaild certificate is solved.
this is my code :

[...]
      apr_array_header_t *providers =
          apr_array_make(pool, 8, sizeof(svn_auth_provider_object_t *));
      svn_auth_provider_object_t *provider;
[...]
      svn_client_get_ssl_server_trust_prompt_provider(
                           &provider, onSslServerTrustPrompt, this, pool);
      *(svn_auth_provider_object_t **)apr_array_push(providers) = provider;
[...]
      svn_auth_baton_t *ab;
      svn_auth_open(&ab, providers, pool);
[...]

      static svn_error_t *
      onSslServerTrustPrompt(svn_auth_cred_ssl_server_trust_t **cred,
                           void *baton,
                           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)
     {
          svn_auth_cred_ssl_server_trust_t *cred_ =
                 (svn_auth_cred_ssl_server_trust_t*)
                 apr_palloc(pool, sizeof(svn_auth_cred_ssl_server_trust_t));
          cred_->may_save = 1;
          cred_->accepted_failures = acceptedFailures;
          *cred = cred_;
          return SVN_NO_ERROR;
     }



--woodsp









At 2016-10-22 04:25:51, "Bert Huijben" <be...@qqmail.nl> wrote:
>
>
>> -----Original Message-----
>> From: Stefan Sperling [mailto:stsp@elego.de]
>> Sent: vrijdag 21 oktober 2016 14:14
>> To: yuan lixin <wo...@126.com>
>> Cc: users@subversion.apache.org
>> Subject: Re: Re: subversion issue: ignore server invaild certificate in
>linux
>> 
>> On Fri, Oct 21, 2016 at 07:41:18PM +0800, yuan lixin wrote:
>> > but in the interface "svn_auth_ssl_server_trust_prompt_func_t",
>> > the actual parameter is "failures", not "*failures".  so it can not
>change
>> > the svn's failures in linux, then can not ignore certificate.
>> > could you look at my code for a solution.
>> >
>> > Thank you
>> > --woodsp
>> 
>> libsvn_subr gets 'failures' from the 'parameters' hash:
>
>Code shouldn't touch the failures value; they should change the
>accepted_failures in the credentials value. 
>
>/** @c SVN_AUTH_CRED_SSL_SERVER_TRUST credentials. */
>typedef struct svn_auth_cred_ssl_server_trust_t
>{
>  /** Indicates if the credentials may be saved (to disk). For example, a
>   * GUI prompt implementation with a checkbox to accept the certificate
>   * permanently shall set @a may_save to TRUE if the checkbox is checked.
>   */
>  svn_boolean_t may_save;
>  /** Bit mask of the accepted failures */
>  apr_uint32_t accepted_failures;
>} svn_auth_cred_ssl_server_trust_t;
>
>
>If svn uses a different way to change a value in the caller that is a bug
>that should be fixed there.
>
>	Bert
>

Re: subversion issue: ignore server invaild certificate in linux

Posted by Branko Čibej <br...@apache.org>.
On 21.10.2016 22:25, Bert Huijben wrote:
>
>> -----Original Message-----
>> From: Stefan Sperling [mailto:stsp@elego.de]
>> Sent: vrijdag 21 oktober 2016 14:14
>> To: yuan lixin <wo...@126.com>
>> Cc: users@subversion.apache.org
>> Subject: Re: Re: subversion issue: ignore server invaild certificate in
> linux
>> On Fri, Oct 21, 2016 at 07:41:18PM +0800, yuan lixin wrote:
>>> but in the interface "svn_auth_ssl_server_trust_prompt_func_t",
>>> the actual parameter is "failures", not "*failures".  so it can not
> change
>>> the svn's failures in linux, then can not ignore certificate.
>>> could you look at my code for a solution.
>>>
>>> Thank you
>>> --woodsp
>> libsvn_subr gets 'failures' from the 'parameters' hash:
> Code shouldn't touch the failures value; they should change the
> accepted_failures in the credentials value. 
>
> /** @c SVN_AUTH_CRED_SSL_SERVER_TRUST credentials. */
> typedef struct svn_auth_cred_ssl_server_trust_t
> {
>   /** Indicates if the credentials may be saved (to disk). For example, a
>    * GUI prompt implementation with a checkbox to accept the certificate
>    * permanently shall set @a may_save to TRUE if the checkbox is checked.
>    */
>   svn_boolean_t may_save;
>   /** Bit mask of the accepted failures */
>   apr_uint32_t accepted_failures;
> } svn_auth_cred_ssl_server_trust_t;
>
>
> If svn uses a different way to change a value in the caller that is a bug
> that should be fixed there.


It does not; we do the right thing, see my other post.

-- Brane

RE: Re: subversion issue: ignore server invaild certificate in linux

Posted by Bert Huijben <be...@qqmail.nl>.

> -----Original Message-----
> From: Stefan Sperling [mailto:stsp@elego.de]
> Sent: vrijdag 21 oktober 2016 14:14
> To: yuan lixin <wo...@126.com>
> Cc: users@subversion.apache.org
> Subject: Re: Re: subversion issue: ignore server invaild certificate in
linux
> 
> On Fri, Oct 21, 2016 at 07:41:18PM +0800, yuan lixin wrote:
> > but in the interface "svn_auth_ssl_server_trust_prompt_func_t",
> > the actual parameter is "failures", not "*failures".  so it can not
change
> > the svn's failures in linux, then can not ignore certificate.
> > could you look at my code for a solution.
> >
> > Thank you
> > --woodsp
> 
> libsvn_subr gets 'failures' from the 'parameters' hash:

Code shouldn't touch the failures value; they should change the
accepted_failures in the credentials value. 

/** @c SVN_AUTH_CRED_SSL_SERVER_TRUST credentials. */
typedef struct svn_auth_cred_ssl_server_trust_t
{
  /** Indicates if the credentials may be saved (to disk). For example, a
   * GUI prompt implementation with a checkbox to accept the certificate
   * permanently shall set @a may_save to TRUE if the checkbox is checked.
   */
  svn_boolean_t may_save;
  /** Bit mask of the accepted failures */
  apr_uint32_t accepted_failures;
} svn_auth_cred_ssl_server_trust_t;


If svn uses a different way to change a value in the caller that is a bug
that should be fixed there.

	Bert


Re: Re: subversion issue: ignore server invaild certificate in linux

Posted by Stefan Sperling <st...@elego.de>.
On Fri, Oct 21, 2016 at 07:41:18PM +0800, yuan lixin wrote:
> but in the interface "svn_auth_ssl_server_trust_prompt_func_t",
> the actual parameter is "failures", not "*failures".  so it can not change
> the svn's failures in linux, then can not ignore certificate.
> could you look at my code for a solution.
> 
> Thank you
> --woodsp

libsvn_subr gets 'failures' from the 'parameters' hash:

https://svn.apache.org/repos/asf/subversion/trunk/subversion/libsvn_subr/ssl_server_trust_providers.c

/* retrieve ssl server CA failure overrides (if any) from servers
   config */
static svn_error_t *
ssl_server_trust_file_first_credentials(void **credentials,
                                        void **iter_baton,
                                        void *provider_baton,
                                        apr_hash_t *parameters,
                                        const char *realmstring,
                                        apr_pool_t *pool)
{
  apr_uint32_t *failures = svn_hash_gets(parameters,
                                         SVN_AUTH_PARAM_SSL_SERVER_FAILURES);
  const svn_auth_ssl_server_cert_info_t *cert_info =
    svn_hash_gets(parameters, SVN_AUTH_PARAM_SSL_SERVER_CERT_INFO);
  apr_hash_t *creds_hash = NULL;
  const char *config_dir;
  svn_error_t *error = SVN_NO_ERROR;

  *credentials = NULL;
  *iter_baton = NULL;

  /* Check if this is a permanently accepted certificate */
  config_dir = svn_hash_gets(parameters, SVN_AUTH_PARAM_CONFIG_DIR);
  error =
    svn_config_read_auth_data(&creds_hash, SVN_AUTH_CRED_SSL_SERVER_TRUST,
                              realmstring, config_dir, pool);
  svn_error_clear(error);
  if (! error && creds_hash)
    {
      svn_string_t *trusted_cert, *this_cert, *failstr;
      apr_uint32_t last_failures = 0;

      trusted_cert = svn_hash_gets(creds_hash, SVN_CONFIG_AUTHN_ASCII_CERT_KEY);
      this_cert = svn_string_create(cert_info->ascii_cert, pool);
      failstr = svn_hash_gets(creds_hash, SVN_CONFIG_AUTHN_FAILURES_KEY);

      if (failstr)
        SVN_ERR(svn_cstring_atoui(&last_failures, failstr->data));

      /* If the cert is trusted and there are no new failures, we
       * accept it by clearing all failures. */
      if (trusted_cert &&
          svn_string_compare(this_cert, trusted_cert) &&
          (*failures & ~last_failures) == 0)
        {
          *failures = 0;
        }
    }

  /* If all failures are cleared now, we return the creds */
  if (! *failures)
    {
      svn_auth_cred_ssl_server_trust_t *creds =
        apr_pcalloc(pool, sizeof(*creds));
      creds->may_save = FALSE; /* No need to save it again... */
      *credentials = creds;
    }

  return SVN_NO_ERROR;
}

[...]

static const svn_auth_provider_t ssl_server_trust_file_provider = {
  SVN_AUTH_CRED_SSL_SERVER_TRUST,
  ssl_server_trust_file_first_credentials,
  NULL,
  ssl_server_trust_file_save_credentials,
};

So I believe you can create an svn_auth_provider_t with your own
implementation of ssl_server_trust_file_first_credentials:

static svn_error_t *
my_own_server_trust_file_first_credentials(void **credentials,
                                        void **iter_baton,
                                        void *provider_baton,
                                        apr_hash_t *parameters,
                                        const char *realmstring,
                                        apr_pool_t *pool)
{
  apr_uint32_t *failures = svn_hash_gets(parameters,
                                         SVN_AUTH_PARAM_SSL_SERVER_FAILURES);
  svn_auth_cred_ssl_server_trust_t *creds =
    apr_pcalloc(pool, sizeof(*creds));
  creds->may_save = FALSE;
  *credentials = creds;

  *failures = 0;

  return SVN_NO_ERROR;
}


And create your own provider:

static const svn_auth_provider_t my_own_server_trust_file_provider = {
  SVN_AUTH_CRED_SSL_SERVER_TRUST,
  my_own_server_trust_file_first_credentials,
  NULL,
  NULL,
};

And somehow register this provider when svn_auth_open() is called.

I don't know if my idea will really work, but I have no idea what else
you could try.