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

« back to all changes in this revision

Viewing changes to subversion/libsvn_ra_svn/cyrus_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:
28
28
#include <apr_want.h>
29
29
#include <apr_general.h>
30
30
#include <apr_strings.h>
31
 
#include <apr_atomic.h>
32
 
#include <apr_thread_mutex.h>
33
31
#include <apr_version.h>
34
32
 
35
33
#include "svn_types.h"
42
40
 
43
41
#include "private/svn_atomic.h"
44
42
#include "private/ra_svn_sasl.h"
 
43
#include "private/svn_mutex.h"
45
44
 
46
45
#include "ra_svn.h"
47
46
 
86
85
static apr_array_header_t *free_mutexes = NULL;
87
86
 
88
87
/* A mutex to serialize access to the array. */
89
 
static apr_thread_mutex_t *array_mutex = NULL;
 
88
static svn_mutex__t *array_mutex = NULL;
90
89
 
91
90
/* Callbacks we pass to sasl_set_mutex(). */
92
91
 
 
92
static svn_error_t *
 
93
sasl_mutex_alloc_cb_internal(svn_mutex__t **mutex)
 
94
{
 
95
  if (apr_is_empty_array(free_mutexes))
 
96
    return svn_mutex__init(mutex, TRUE, sasl_pool);
 
97
  else
 
98
    *mutex = *((svn_mutex__t**)apr_array_pop(free_mutexes));
 
99
 
 
100
  return SVN_NO_ERROR;
 
101
}
 
102
 
93
103
static void *sasl_mutex_alloc_cb(void)
94
104
{
95
 
  apr_thread_mutex_t *mutex;
96
 
  apr_status_t apr_err;
 
105
  svn_mutex__t *mutex = NULL;
 
106
  svn_error_t *err;
97
107
 
98
108
  if (!svn_ra_svn__sasl_status)
99
109
    return NULL;
100
110
 
101
 
  apr_err = apr_thread_mutex_lock(array_mutex);
102
 
  if (apr_err != APR_SUCCESS)
103
 
    return NULL;
104
 
 
105
 
  if (apr_is_empty_array(free_mutexes))
106
 
    {
107
 
      apr_err = apr_thread_mutex_create(&mutex,
108
 
                                        APR_THREAD_MUTEX_DEFAULT,
109
 
                                        sasl_pool);
110
 
      if (apr_err != APR_SUCCESS)
111
 
        mutex = NULL;
112
 
    }
 
111
  err = svn_mutex__lock(array_mutex);
 
112
  if (err)
 
113
    svn_error_clear(err);
113
114
  else
114
 
    mutex = *((apr_thread_mutex_t**)apr_array_pop(free_mutexes));
115
 
 
116
 
  apr_err = apr_thread_mutex_unlock(array_mutex);
117
 
  if (apr_err != APR_SUCCESS)
118
 
    return NULL;
 
115
    svn_error_clear(svn_mutex__unlock(array_mutex,
 
116
                                      sasl_mutex_alloc_cb_internal(&mutex)));
119
117
 
120
118
  return mutex;
121
119
}
122
120
 
 
121
static int check_result(svn_error_t *err)
 
122
{
 
123
  if (err)
 
124
    {
 
125
      svn_error_clear(err);
 
126
      return -1;
 
127
    }
 
128
 
 
129
  return 0;
 
130
}
 
131
 
123
132
static int sasl_mutex_lock_cb(void *mutex)
124
133
{
125
134
  if (!svn_ra_svn__sasl_status)
126
135
    return 0;
127
 
  return (apr_thread_mutex_lock(mutex) == APR_SUCCESS) ? 0 : -1;
 
136
  return check_result(svn_mutex__lock(mutex));
128
137
}
129
138
 
130
139
static int sasl_mutex_unlock_cb(void *mutex)
131
140
{
132
141
  if (!svn_ra_svn__sasl_status)
133
142
    return 0;
134
 
  return (apr_thread_mutex_unlock(mutex) == APR_SUCCESS) ? 0 : -1;
 
143
  return check_result(svn_mutex__unlock(mutex, SVN_NO_ERROR));
 
144
}
 
145
 
 
146
static svn_error_t *
 
147
sasl_mutex_free_cb_internal(void *mutex)
 
148
{
 
149
  APR_ARRAY_PUSH(free_mutexes, svn_mutex__t*) = mutex;
 
150
  return SVN_NO_ERROR;
135
151
}
136
152
 
137
153
static void sasl_mutex_free_cb(void *mutex)
138
154
{
139
 
  if (svn_ra_svn__sasl_status)
140
 
    {
141
 
      apr_status_t apr_err = apr_thread_mutex_lock(array_mutex);
142
 
      if (apr_err == APR_SUCCESS)
143
 
        {
144
 
          APR_ARRAY_PUSH(free_mutexes, apr_thread_mutex_t*) = mutex;
145
 
          apr_thread_mutex_unlock(array_mutex);
146
 
        }
147
 
    }
 
155
  svn_error_t *err;
 
156
 
 
157
  if (!svn_ra_svn__sasl_status)
 
158
    return;
 
159
 
 
160
  err = svn_mutex__lock(array_mutex);
 
161
  if (err)
 
162
    svn_error_clear(err);
 
163
  else
 
164
    svn_error_clear(svn_mutex__unlock(array_mutex,
 
165
                                      sasl_mutex_free_cb_internal(mutex)));
148
166
}
149
167
#endif /* APR_HAS_THREADS */
150
168
 
151
 
apr_status_t svn_ra_svn__sasl_common_init(apr_pool_t *pool)
 
169
svn_error_t *
 
170
svn_ra_svn__sasl_common_init(apr_pool_t *pool)
152
171
{
153
 
  apr_status_t apr_err = APR_SUCCESS;
154
 
 
155
172
  sasl_pool = svn_pool_create(pool);
156
173
  sasl_ctx_count = 1;
157
174
  apr_pool_cleanup_register(sasl_pool, NULL, sasl_done_cb,
161
178
                 sasl_mutex_lock_cb,
162
179
                 sasl_mutex_unlock_cb,
163
180
                 sasl_mutex_free_cb);
164
 
  free_mutexes = apr_array_make(sasl_pool, 0, sizeof(apr_thread_mutex_t *));
165
 
  apr_err = apr_thread_mutex_create(&array_mutex,
166
 
                                    APR_THREAD_MUTEX_DEFAULT,
167
 
                                    sasl_pool);
 
181
  free_mutexes = apr_array_make(sasl_pool, 0, sizeof(svn_mutex__t *));
 
182
  SVN_ERR(svn_mutex__init(&array_mutex, TRUE, sasl_pool));
 
183
 
168
184
#endif /* APR_HAS_THREADS */
169
 
  return apr_err;
 
185
 
 
186
  return SVN_NO_ERROR;
170
187
}
171
188
 
172
189
/* We are going to look at errno when we get SASL_FAIL but we don't
213
230
{
214
231
  int result;
215
232
 
216
 
  if (svn_ra_svn__sasl_common_init(pool) != APR_SUCCESS)
217
 
    return svn_error_create(SVN_ERR_RA_NOT_AUTHORIZED, NULL,
218
 
                            _("Could not initialize the SASL library"));
 
233
  SVN_ERR(svn_ra_svn__sasl_common_init(pool));
219
234
  clear_sasl_errno();
220
235
  result = sasl_client_init(NULL);
221
236
  if (result != SASL_OK)
492
507
  while (result == SASL_CONTINUE)
493
508
    {
494
509
      /* Read the server response */
495
 
      SVN_ERR(svn_ra_svn_read_tuple(sess->conn, pool, "w(?s)",
496
 
                                    &status, &in));
 
510
      SVN_ERR(svn_ra_svn__read_tuple(sess->conn, pool, "w(?s)",
 
511
                                     &status, &in));
497
512
 
498
513
      if (strcmp(status, "failure") == 0)
499
514
        {
518
533
      clear_sasl_errno();
519
534
      result = sasl_client_step(sasl_ctx,
520
535
                                in->data,
521
 
                                in->len,
 
536
                                (const unsigned int) in->len,
522
537
                                &client_interact,
523
538
                                &out, /* Filled in by SASL. */
524
539
                                &outlen);
538
553
          /* For CRAM-MD5, we don't use base64-encoding. */
539
554
          if (strcmp(mech, "CRAM-MD5") != 0)
540
555
            arg = svn_base64_encode_string2(arg, TRUE, pool);
541
 
          SVN_ERR(svn_ra_svn_write_cstring(sess->conn, pool, arg->data));
 
556
          SVN_ERR(svn_ra_svn__write_cstring(sess->conn, pool, arg->data));
542
557
        }
543
558
      else
544
559
        {
545
 
          SVN_ERR(svn_ra_svn_write_cstring(sess->conn, pool, ""));
 
560
          SVN_ERR(svn_ra_svn__write_cstring(sess->conn, pool, ""));
546
561
        }
547
562
    }
548
563
 
549
564
  if (!status || strcmp(status, "step") == 0)
550
565
    {
551
566
      /* This is a client-send-last mech.  Read the last server response. */
552
 
      SVN_ERR(svn_ra_svn_read_tuple(sess->conn, pool, "w(?s)",
 
567
      SVN_ERR(svn_ra_svn__read_tuple(sess->conn, pool, "w(?s)",
553
568
              &status, &in));
554
569
 
555
570
      if (strcmp(status, "failure") == 0)
605
620
          return SVN_NO_ERROR;
606
621
        }
607
622
      clear_sasl_errno();
608
 
      result = sasl_decode(sasl_baton->ctx, buffer, len2,
 
623
      result = sasl_decode(sasl_baton->ctx, buffer, (unsigned int) len2,
609
624
                           &sasl_baton->read_buf,
610
625
                           &sasl_baton->read_len);
611
626
      if (result != SASL_OK)
647
662
      /* Make sure we don't write too much. */
648
663
      *len = (*len > sasl_baton->maxsize) ? sasl_baton->maxsize : *len;
649
664
      clear_sasl_errno();
650
 
      result = sasl_encode(sasl_baton->ctx, buffer, *len,
 
665
      result = sasl_encode(sasl_baton->ctx, buffer, (unsigned int) *len,
651
666
                           &sasl_baton->write_buf,
652
667
                           &sasl_baton->write_len);
653
668
 
719
734
          const void *maxsize;
720
735
 
721
736
          /* Flush the connection, as we're about to replace its stream. */
722
 
          SVN_ERR(svn_ra_svn_flush(conn, pool));
 
737
          SVN_ERR(svn_ra_svn__flush(conn, pool));
723
738
 
724
739
          /* Create and initialize the stream baton. */
725
740
          sasl_baton = apr_pcalloc(conn->pool, sizeof(*sasl_baton));
740
755
            {
741
756
              clear_sasl_errno();
742
757
              result = sasl_decode(sasl_ctx, conn->read_ptr,
743
 
                                   conn->read_end - conn->read_ptr,
744
 
                                   &sasl_baton->read_buf,
745
 
                                   &sasl_baton->read_len);
 
758
                             (unsigned int) (conn->read_end - conn->read_ptr),
 
759
                             &sasl_baton->read_buf, &sasl_baton->read_len);
746
760
              if (result != SASL_OK)
747
761
                return svn_error_create(SVN_ERR_RA_NOT_AUTHORIZED, NULL,
748
762
                                        get_sasl_error(sasl_ctx, result, pool));
812
826
  const char *local_addrport = NULL, *remote_addrport = NULL;
813
827
  svn_boolean_t success;
814
828
  sasl_callback_t *callbacks;
815
 
  cred_baton_t cred_baton;
 
829
  cred_baton_t cred_baton = { 0 };
816
830
  int i;
817
831
 
818
832
  if (!sess->is_tunneled)
842
856
  realmstring = apr_psprintf(pool, "%s %s", sess->realm_prefix, realm);
843
857
 
844
858
  /* Initialize the credential baton. */
845
 
  memset(&cred_baton, 0, sizeof(cred_baton));
846
859
  cred_baton.auth_baton = sess->callbacks->auth_baton;
847
860
  cred_baton.realmstring = realmstring;
848
861
  cred_baton.pool = pool;
858
871
 
859
872
  /* The username callback. */
860
873
  callbacks[0].id = SASL_CB_AUTHNAME;
861
 
  callbacks[0].proc = get_username_cb;
 
874
  callbacks[0].proc = (int (*)(void))get_username_cb;
862
875
  callbacks[0].context = &cred_baton;
863
876
 
864
877
  /* The password callback. */
865
878
  callbacks[1].id = SASL_CB_PASS;
866
 
  callbacks[1].proc = get_password_cb;
 
879
  callbacks[1].proc = (int (*)(void))get_password_cb;
867
880
  callbacks[1].context = &cred_baton;
868
881
 
869
882
  /* Mark the end of the array. */
896
909
          return cred_baton.err;
897
910
        }
898
911
      if (cred_baton.no_more_creds
899
 
          || (! success && ! err && ! cred_baton.was_used))
 
912
          || (! err && ! success && ! cred_baton.was_used))
900
913
        {
901
914
          svn_error_clear(err);
902
915
          /* If we ran out of authentication providers, or if we got a server