~ubuntu-branches/debian/sid/subversion/sid

« back to all changes in this revision

Viewing changes to subversion/libsvn_subr/auth.c

  • Committer: Package Import Robot
  • Author(s): James McCoy, Peter Samuelson, James McCoy
  • Date: 2014-01-12 19:48:33 UTC
  • mfrom: (0.2.10)
  • Revision ID: package-import@ubuntu.com-20140112194833-w3axfwksn296jn5x
Tags: 1.8.5-1
[ Peter Samuelson ]
* New upstream release.  (Closes: #725787) Rediff patches:
  - Remove apr-abi1 (applied upstream), rename apr-abi2 to apr-abi
  - Remove loosen-sqlite-version-check (shouldn't be needed)
  - Remove java-osgi-metadata (applied upstream)
  - svnmucc prompts for a changelog if none is provided. (Closes: #507430)
  - Remove fix-bdb-version-detection, upstream uses "apu-config --dbm-libs"
  - Remove ruby-test-wc (applied upstream)
  - Fix “svn diff -r N file” when file has svn:mime-type set.
    (Closes: #734163)
  - Support specifying an encoding for mod_dav_svn's environment in which
    hooks are run.  (Closes: #601544)
  - Fix ordering of “svnadmin dump” paths with certain APR versions.
    (Closes: #687291)
  - Provide a better error message when authentication fails with an
    svn+ssh:// URL.  (Closes: #273874)
  - Updated Polish translations.  (Closes: #690815)

[ James McCoy ]
* Remove all traces of libneon, replaced by libserf.
* patches/sqlite_3.8.x_workaround: Upstream fix for wc-queries-test test
  failurse.
* Run configure with --with-apache-libexecdir, which allows removing part of
  patches/rpath.
* Re-enable auth-test as upstream has fixed the problem of picking up
  libraries from the environment rather than the build tree.
  (Closes: #654172)
* Point LD_LIBRARY_PATH at the built auth libraries when running the svn
  command during the build.  (Closes: #678224)
* Add a NEWS entry describing how to configure mod_dav_svn to understand
  UTF-8.  (Closes: #566148)
* Remove ancient transitional package, libsvn-ruby.
* Enable compatibility with Sqlite3 versions back to Wheezy.
* Enable hardening flags.  (Closes: #734918)
* patches/build-fixes: Enable verbose build logs.
* Build against the default ruby version.  (Closes: #722393)

Show diffs side-by-side

added added

removed removed

Lines of Context:
26
26
#include <apr_tables.h>
27
27
#include <apr_strings.h>
28
28
 
 
29
#include "svn_hash.h"
29
30
#include "svn_types.h"
30
31
#include "svn_string.h"
31
32
#include "svn_error.h"
34
35
#include "svn_private_config.h"
35
36
#include "svn_dso.h"
36
37
#include "svn_version.h"
37
 
 
38
 
/* The good way to think of this machinery is as a set of tables.
39
 
 
40
 
   - Each type of credentials selects a single table.
41
 
 
42
 
   - In a given table, each row is a 'provider' capable of returning
43
 
     the same type of credentials.  Each column represents a
44
 
     provider's repeated attempts to provide credentials.
 
38
#include "private/svn_dep_compat.h"
 
39
#include "private/svn_subr_private.h"
 
40
 
 
41
#include "auth.h"
 
42
 
 
43
/* AN OVERVIEW
 
44
   ===========
 
45
 
 
46
   A good way to think of this machinery is as a set of tables.
 
47
 
 
48
     - Each type of credentials selects a single table.
 
49
 
 
50
     - In a given table, each row is a 'provider' capable of returning
 
51
       the same type of credentials.  Each column represents a
 
52
       provider's repeated attempts to provide credentials.
 
53
 
 
54
 
 
55
   Fetching Credentials from Providers
 
56
   -----------------------------------
45
57
 
46
58
   When the caller asks for a particular type of credentials, the
47
59
   machinery in this file walks over the appropriate table.  It starts
55
67
 
56
68
   Note that the caller cannot see the table traversal, and thus has
57
69
   no idea when we switch providers.
 
70
 
 
71
 
 
72
   Storing Credentials with Providers
 
73
   ----------------------------------
 
74
 
 
75
   When the server has validated a set of credentials, and when
 
76
   credential caching is enabled, we have the chance to store those
 
77
   credentials for later use.  The provider which provided the working
 
78
   credentials is the first one given the opportunity to (re)cache
 
79
   those credentials.  Its save_credentials() function is invoked with
 
80
   the working credentials.  If that provider reports that it
 
81
   successfully stored the credentials, we're done.  Otherwise, we
 
82
   walk the providers (rows) for that type of credentials in order
 
83
   from the top of the table, allowing each in turn the opportunity to
 
84
   store the credentials.  When one reports that it has done so
 
85
   successfully -- or when we run out of providers (rows) to try --
 
86
   the table walk ends.
58
87
*/
59
88
 
60
89
 
125
154
      provider = APR_ARRAY_IDX(providers, i, svn_auth_provider_object_t *);
126
155
 
127
156
      /* Add it to the appropriate table in the auth_baton */
128
 
      table = apr_hash_get(ab->tables,
129
 
                           provider->vtable->cred_kind, APR_HASH_KEY_STRING);
 
157
      table = svn_hash_gets(ab->tables, provider->vtable->cred_kind);
130
158
      if (! table)
131
159
        {
132
160
          table = apr_pcalloc(pool, sizeof(*table));
133
161
          table->providers
134
162
            = apr_array_make(pool, 1, sizeof(svn_auth_provider_object_t *));
135
163
 
136
 
          apr_hash_set(ab->tables,
137
 
                       provider->vtable->cred_kind, APR_HASH_KEY_STRING,
138
 
                       table);
 
164
          svn_hash_sets(ab->tables, provider->vtable->cred_kind, table);
139
165
        }
140
166
      APR_ARRAY_PUSH(table->providers, svn_auth_provider_object_t *)
141
167
        = provider;
151
177
                       const char *name,
152
178
                       const void *value)
153
179
{
154
 
  apr_hash_set(auth_baton->parameters, name, APR_HASH_KEY_STRING, value);
 
180
  svn_hash_sets(auth_baton->parameters, name, value);
155
181
}
156
182
 
157
183
const void *
158
184
svn_auth_get_parameter(svn_auth_baton_t *auth_baton,
159
185
                       const char *name)
160
186
{
161
 
  return apr_hash_get(auth_baton->parameters, name, APR_HASH_KEY_STRING);
162
 
}
163
 
 
164
 
 
 
187
  return svn_hash_gets(auth_baton->parameters, name);
 
188
}
 
189
 
 
190
 
 
191
/* Return the key used to address the in-memory cache of auth
 
192
   credentials of type CRED_KIND and associated with REALMSTRING. */
 
193
static const char *
 
194
make_cache_key(const char *cred_kind,
 
195
               const char *realmstring,
 
196
               apr_pool_t *pool)
 
197
{
 
198
  return apr_pstrcat(pool, cred_kind, ":", realmstring, (char *)NULL);
 
199
}
165
200
 
166
201
svn_error_t *
167
202
svn_auth_first_credentials(void **credentials,
181
216
  const char *cache_key;
182
217
 
183
218
  /* Get the appropriate table of providers for CRED_KIND. */
184
 
  table = apr_hash_get(auth_baton->tables, cred_kind, APR_HASH_KEY_STRING);
 
219
  table = svn_hash_gets(auth_baton->tables, cred_kind);
185
220
  if (! table)
186
221
    return svn_error_createf(SVN_ERR_AUTHN_NO_PROVIDER, NULL,
187
222
                             _("No provider registered for '%s' credentials"),
188
223
                             cred_kind);
189
224
 
190
225
  /* First, see if we have cached creds in the auth_baton. */
191
 
  cache_key = apr_pstrcat(pool, cred_kind, ":", realmstring, (char *)NULL);
192
 
  creds = apr_hash_get(auth_baton->creds_cache,
193
 
                       cache_key, APR_HASH_KEY_STRING);
 
226
  cache_key = make_cache_key(cred_kind, realmstring, pool);
 
227
  creds = svn_hash_gets(auth_baton->creds_cache, cache_key);
194
228
  if (creds)
195
229
    {
196
230
       got_first = FALSE;
203
237
        {
204
238
          provider = APR_ARRAY_IDX(table->providers, i,
205
239
                                   svn_auth_provider_object_t *);
206
 
          SVN_ERR(provider->vtable->first_credentials
207
 
                  (&creds, &iter_baton, provider->provider_baton,
208
 
                   auth_baton->parameters, realmstring, auth_baton->pool));
 
240
          SVN_ERR(provider->vtable->first_credentials(&creds, &iter_baton,
 
241
                                                      provider->provider_baton,
 
242
                                                      auth_baton->parameters,
 
243
                                                      realmstring,
 
244
                                                      auth_baton->pool));
209
245
 
210
246
          if (creds != NULL)
211
247
            {
231
267
      *state = iterstate;
232
268
 
233
269
      /* Put the creds in the cache */
234
 
      apr_hash_set(auth_baton->creds_cache,
235
 
                   apr_pstrdup(auth_baton->pool, cache_key),
236
 
                   APR_HASH_KEY_STRING,
237
 
                   creds);
 
270
      svn_hash_sets(auth_baton->creds_cache,
 
271
                    apr_pstrdup(auth_baton->pool, cache_key),
 
272
                    creds);
238
273
    }
239
274
 
240
275
  *credentials = creds;
263
298
                               svn_auth_provider_object_t *);
264
299
      if (! state->got_first)
265
300
        {
266
 
          SVN_ERR(provider->vtable->first_credentials
267
 
                  (&creds, &(state->provider_iter_baton),
268
 
                   provider->provider_baton, auth_baton->parameters,
269
 
                   state->realmstring, auth_baton->pool));
 
301
          SVN_ERR(provider->vtable->first_credentials(
 
302
                      &creds, &(state->provider_iter_baton),
 
303
                      provider->provider_baton, auth_baton->parameters,
 
304
                      state->realmstring, auth_baton->pool));
270
305
          state->got_first = TRUE;
271
306
        }
272
 
      else
 
307
      else if (provider->vtable->next_credentials)
273
308
        {
274
 
          if (provider->vtable->next_credentials)
275
 
            SVN_ERR(provider->vtable->next_credentials
276
 
                    (&creds, state->provider_iter_baton,
277
 
                     provider->provider_baton, auth_baton->parameters,
278
 
                     state->realmstring, auth_baton->pool));
 
309
          SVN_ERR(provider->vtable->next_credentials(
 
310
                      &creds, state->provider_iter_baton,
 
311
                      provider->provider_baton, auth_baton->parameters,
 
312
                      state->realmstring, auth_baton->pool));
279
313
        }
280
314
 
281
315
      if (creds != NULL)
282
316
        {
283
317
          /* Put the creds in the cache */
284
 
          apr_hash_set(auth_baton->creds_cache,
285
 
                       state->cache_key, APR_HASH_KEY_STRING,
286
 
                       creds);
 
318
          svn_hash_sets(auth_baton->creds_cache, state->cache_key, creds);
287
319
          break;
288
320
        }
289
321
 
311
343
    return SVN_NO_ERROR;
312
344
 
313
345
  auth_baton = state->auth_baton;
314
 
  creds = apr_hash_get(state->auth_baton->creds_cache,
315
 
                       state->cache_key, APR_HASH_KEY_STRING);
 
346
  creds = svn_hash_gets(state->auth_baton->creds_cache, state->cache_key);
316
347
  if (! creds)
317
348
    return SVN_NO_ERROR;
318
349
 
319
350
  /* Do not save the creds if SVN_AUTH_PARAM_NO_AUTH_CACHE is set */
320
 
  no_auth_cache = apr_hash_get(auth_baton->parameters,
321
 
                               SVN_AUTH_PARAM_NO_AUTH_CACHE,
322
 
                               APR_HASH_KEY_STRING);
 
351
  no_auth_cache = svn_hash_gets(auth_baton->parameters,
 
352
                                SVN_AUTH_PARAM_NO_AUTH_CACHE);
323
353
  if (no_auth_cache)
324
354
    return SVN_NO_ERROR;
325
355
 
362
392
  return SVN_NO_ERROR;
363
393
}
364
394
 
 
395
 
 
396
svn_error_t *
 
397
svn_auth_forget_credentials(svn_auth_baton_t *auth_baton,
 
398
                            const char *cred_kind,
 
399
                            const char *realmstring,
 
400
                            apr_pool_t *scratch_pool)
 
401
{
 
402
  SVN_ERR_ASSERT((cred_kind && realmstring) || (!cred_kind && !realmstring));
 
403
 
 
404
  /* If we have a CRED_KIND and REALMSTRING, we clear out just the
 
405
     cached item (if any).  Otherwise, empty the whole hash. */
 
406
  if (cred_kind)
 
407
    {
 
408
      svn_hash_sets(auth_baton->creds_cache,
 
409
                    make_cache_key(cred_kind, realmstring, scratch_pool),
 
410
                    NULL);
 
411
    }
 
412
  else
 
413
    {
 
414
      apr_hash_clear(auth_baton->creds_cache);
 
415
    }
 
416
 
 
417
  return SVN_NO_ERROR;
 
418
}
 
419
 
 
420
 
365
421
svn_auth_ssl_server_cert_info_t *
366
422
svn_auth_ssl_server_cert_info_dup
367
423
  (const svn_auth_ssl_server_cert_info_t *info, apr_pool_t *pool)
382
438
}
383
439
 
384
440
svn_error_t *
385
 
svn_auth_get_platform_specific_provider
386
 
  (svn_auth_provider_object_t **provider,
387
 
   const char *provider_name,
388
 
   const char *provider_type,
389
 
   apr_pool_t *pool)
 
441
svn_auth_get_platform_specific_provider(svn_auth_provider_object_t **provider,
 
442
                                        const char *provider_name,
 
443
                                        const char *provider_type,
 
444
                                        apr_pool_t *pool)
390
445
{
391
446
  *provider = NULL;
392
447
 
399
454
      const char *library_label, *library_name;
400
455
      const char *provider_function_name, *version_function_name;
401
456
      library_name = apr_psprintf(pool,
402
 
                                  "libsvn_auth_%s-%d.so.0",
 
457
                                  "libsvn_auth_%s-%d.so.%d",
403
458
                                  provider_name,
404
 
                                  SVN_VER_MAJOR);
 
459
                                  SVN_VER_MAJOR, SVN_SOVERSION);
405
460
      library_label = apr_psprintf(pool, "svn_%s", provider_name);
406
461
      provider_function_name = apr_psprintf(pool,
407
462
                                            "svn_auth_get_%s_%s_provider",
424
479
              check_list[0].version_query = version_function;
425
480
              check_list[1].label = NULL;
426
481
              check_list[1].version_query = NULL;
427
 
              SVN_ERR(svn_ver_check_list(svn_subr_version(), check_list));
 
482
              SVN_ERR(svn_ver_check_list2(svn_subr_version(), check_list,
 
483
                                          svn_ver_equal));
428
484
            }
429
485
          if (apr_dso_sym(&provider_function_symbol,
430
486
                          dso,
448
504
    }
449
505
  else
450
506
    {
 
507
#if defined(SVN_HAVE_GPG_AGENT)
 
508
      if (strcmp(provider_name, "gpg_agent") == 0 &&
 
509
          strcmp(provider_type, "simple") == 0)
 
510
        {
 
511
          svn_auth_get_gpg_agent_simple_provider(provider, pool);
 
512
        }
 
513
#endif
451
514
#ifdef SVN_HAVE_KEYCHAIN_SERVICES
452
515
      if (strcmp(provider_name, "keychain") == 0 &&
453
516
          strcmp(provider_type, "simple") == 0)
484
547
}
485
548
 
486
549
svn_error_t *
487
 
svn_auth_get_platform_specific_client_providers
488
 
  (apr_array_header_t **providers,
489
 
   svn_config_t *config,
490
 
   apr_pool_t *pool)
 
550
svn_auth_get_platform_specific_client_providers(apr_array_header_t **providers,
 
551
                                                svn_config_t *config,
 
552
                                                apr_pool_t *pool)
491
553
{
492
554
  svn_auth_provider_object_t *provider;
493
555
  const char *password_stores_config_option;
497
559
#define SVN__MAYBE_ADD_PROVIDER(list, p) \
498
560
  { if (p) APR_ARRAY_PUSH(list, svn_auth_provider_object_t *) = p; }
499
561
 
 
562
#define SVN__DEFAULT_AUTH_PROVIDER_LIST \
 
563
         "gnome-keyring,kwallet,keychain,gpg-agent,windows-cryptoapi"
 
564
 
500
565
  *providers = apr_array_make(pool, 12, sizeof(svn_auth_provider_object_t *));
501
566
 
502
567
  /* Fetch the configured list of password stores, and split them into
505
570
                 &password_stores_config_option,
506
571
                 SVN_CONFIG_SECTION_AUTH,
507
572
                 SVN_CONFIG_OPTION_PASSWORD_STORES,
508
 
                 "gnome-keyring,kwallet,keychain,windows-cryptoapi");
 
573
                 SVN__DEFAULT_AUTH_PROVIDER_LIST);
509
574
  password_stores = svn_cstring_split(password_stores_config_option,
510
575
                                      " ,", TRUE, pool);
511
576
 
529
594
                                                          pool));
530
595
          SVN__MAYBE_ADD_PROVIDER(*providers, provider);
531
596
        }
 
597
      /* GPG-AGENT */
 
598
      else if (apr_strnatcmp(password_store, "gpg-agent") == 0)
 
599
        {
 
600
          SVN_ERR(svn_auth_get_platform_specific_provider(&provider,
 
601
                                                          "gpg_agent",
 
602
                                                          "simple",
 
603
                                                          pool));
 
604
          SVN__MAYBE_ADD_PROVIDER(*providers, provider);
 
605
        }
532
606
      /* KWallet */
533
607
      else if (apr_strnatcmp(password_store, "kwallet") == 0)
534
608
        {