86
85
static apr_array_header_t *free_mutexes = NULL;
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;
91
90
/* Callbacks we pass to sasl_set_mutex(). */
93
sasl_mutex_alloc_cb_internal(svn_mutex__t **mutex)
95
if (apr_is_empty_array(free_mutexes))
96
return svn_mutex__init(mutex, TRUE, sasl_pool);
98
*mutex = *((svn_mutex__t**)apr_array_pop(free_mutexes));
93
103
static void *sasl_mutex_alloc_cb(void)
95
apr_thread_mutex_t *mutex;
105
svn_mutex__t *mutex = NULL;
98
108
if (!svn_ra_svn__sasl_status)
101
apr_err = apr_thread_mutex_lock(array_mutex);
102
if (apr_err != APR_SUCCESS)
105
if (apr_is_empty_array(free_mutexes))
107
apr_err = apr_thread_mutex_create(&mutex,
108
APR_THREAD_MUTEX_DEFAULT,
110
if (apr_err != APR_SUCCESS)
111
err = svn_mutex__lock(array_mutex);
113
svn_error_clear(err);
114
mutex = *((apr_thread_mutex_t**)apr_array_pop(free_mutexes));
116
apr_err = apr_thread_mutex_unlock(array_mutex);
117
if (apr_err != APR_SUCCESS)
115
svn_error_clear(svn_mutex__unlock(array_mutex,
116
sasl_mutex_alloc_cb_internal(&mutex)));
121
static int check_result(svn_error_t *err)
125
svn_error_clear(err);
123
132
static int sasl_mutex_lock_cb(void *mutex)
125
134
if (!svn_ra_svn__sasl_status)
127
return (apr_thread_mutex_lock(mutex) == APR_SUCCESS) ? 0 : -1;
136
return check_result(svn_mutex__lock(mutex));
130
139
static int sasl_mutex_unlock_cb(void *mutex)
132
141
if (!svn_ra_svn__sasl_status)
134
return (apr_thread_mutex_unlock(mutex) == APR_SUCCESS) ? 0 : -1;
143
return check_result(svn_mutex__unlock(mutex, SVN_NO_ERROR));
147
sasl_mutex_free_cb_internal(void *mutex)
149
APR_ARRAY_PUSH(free_mutexes, svn_mutex__t*) = mutex;
137
153
static void sasl_mutex_free_cb(void *mutex)
139
if (svn_ra_svn__sasl_status)
141
apr_status_t apr_err = apr_thread_mutex_lock(array_mutex);
142
if (apr_err == APR_SUCCESS)
144
APR_ARRAY_PUSH(free_mutexes, apr_thread_mutex_t*) = mutex;
145
apr_thread_mutex_unlock(array_mutex);
157
if (!svn_ra_svn__sasl_status)
160
err = svn_mutex__lock(array_mutex);
162
svn_error_clear(err);
164
svn_error_clear(svn_mutex__unlock(array_mutex,
165
sasl_mutex_free_cb_internal(mutex)));
149
167
#endif /* APR_HAS_THREADS */
151
apr_status_t svn_ra_svn__sasl_common_init(apr_pool_t *pool)
170
svn_ra_svn__sasl_common_init(apr_pool_t *pool)
153
apr_status_t apr_err = APR_SUCCESS;
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,
181
free_mutexes = apr_array_make(sasl_pool, 0, sizeof(svn_mutex__t *));
182
SVN_ERR(svn_mutex__init(&array_mutex, TRUE, sasl_pool));
168
184
#endif /* APR_HAS_THREADS */
172
189
/* We are going to look at errno when we get SASL_FAIL but we don't
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));
545
SVN_ERR(svn_ra_svn_write_cstring(sess->conn, pool, ""));
560
SVN_ERR(svn_ra_svn__write_cstring(sess->conn, pool, ""));
549
564
if (!status || strcmp(status, "step") == 0)
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)",
555
570
if (strcmp(status, "failure") == 0)
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));
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;
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;
869
882
/* Mark the end of the array. */