Merge lp:~dave-terei/libmemcached/libmemcached into lp:libmemcached
- libmemcached
- Merge into 1.2
Proposed by
David Terei
Status: | Needs review |
---|---|
Proposed branch: | lp:~dave-terei/libmemcached/libmemcached |
Merge into: | lp:libmemcached |
Diff against target: |
899 lines (+403/-345) 8 files modified
bootstrap.sh (+10/-1) libmemcached-1.2/include.am (+1/-0) libmemcached-1.2/isasl.h (+92/-0) libmemcached-1.2/sasl.h (+1/-5) libmemcached-1.2/struct/sasl.h (+2/-6) libmemcached/include.am (+1/-0) libmemcached/sasl.cc (+104/-333) libmemcached/sasl_client.cc (+192/-0) |
To merge this branch: | bzr merge lp:~dave-terei/libmemcached/libmemcached |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Tangent Trunk | Pending | ||
Review via email: mp+224003@code.launchpad.net |
Commit message
Description of the change
Move to an internal SASL library taken from the membase guys. This removes the dependency on Cyrus SASL. It only supports PLAIN authentication, which seems fine as it's the only authentication mechanism other clients and memcached itself appears to support.
This enables SASL auth to be on by default which has great flow on effects for the community as right now most clients don't support SASL since they can't rely on libmemcached supporting it.
The removal of libsasl isn't complete (i.e., from configure scripts and build system) but I don't have a great grasp of that stuff. This is a initial step in the direction where the final stages of cleaning up should be trivial for someone who knows the code base.
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'bootstrap.sh' | |||
2 | --- bootstrap.sh 2014-02-16 11:31:04 +0000 | |||
3 | +++ bootstrap.sh 2014-06-20 23:47:25 +0000 | |||
4 | @@ -191,6 +191,9 @@ | |||
5 | 191 | opensuse) | 191 | opensuse) |
6 | 192 | VENDOR_DISTRIBUTION='opensuse' | 192 | VENDOR_DISTRIBUTION='opensuse' |
7 | 193 | ;; | 193 | ;; |
8 | 194 | arch) | ||
9 | 195 | VENDOR_DISTRIBUTION='arch' | ||
10 | 196 | ;; | ||
11 | 194 | *) | 197 | *) |
12 | 195 | die "attempt to set an invalid VENDOR_DISTRIBUTION=$dist" | 198 | die "attempt to set an invalid VENDOR_DISTRIBUTION=$dist" |
13 | 196 | ;; | 199 | ;; |
14 | @@ -262,6 +265,9 @@ | |||
15 | 262 | opensuse) | 265 | opensuse) |
16 | 263 | VENDOR_RELEASE="$release" | 266 | VENDOR_RELEASE="$release" |
17 | 264 | ;; | 267 | ;; |
18 | 268 | arch) | ||
19 | 269 | VENDOR_RELEASE="$release" | ||
20 | 270 | ;; | ||
21 | 265 | unknown) | 271 | unknown) |
22 | 266 | die "attempt to set VENDOR_RELEASE without setting VENDOR_DISTRIBUTION" | 272 | die "attempt to set VENDOR_RELEASE without setting VENDOR_DISTRIBUTION" |
23 | 267 | ;; | 273 | ;; |
24 | @@ -311,8 +317,11 @@ | |||
25 | 311 | suse) | 317 | suse) |
26 | 312 | VENDOR='suse' | 318 | VENDOR='suse' |
27 | 313 | ;; | 319 | ;; |
28 | 320 | arch) | ||
29 | 321 | VENDOR='arch' | ||
30 | 322 | ;; | ||
31 | 314 | *) | 323 | *) |
33 | 315 | die "An attempt was made to set an invalid VENDOR=$_vendor" | 324 | die "An attempt was made to set an invalid VENDOR=$vendor" |
34 | 316 | ;; | 325 | ;; |
35 | 317 | esac | 326 | esac |
36 | 318 | 327 | ||
37 | 319 | 328 | ||
38 | === modified file 'libmemcached-1.2/include.am' | |||
39 | --- libmemcached-1.2/include.am 2013-06-11 12:31:47 +0000 | |||
40 | +++ libmemcached-1.2/include.am 2014-06-20 23:47:25 +0000 | |||
41 | @@ -33,6 +33,7 @@ | |||
42 | 33 | nobase_include_HEADERS+= libmemcached-1.2/flush_buffers.h | 33 | nobase_include_HEADERS+= libmemcached-1.2/flush_buffers.h |
43 | 34 | nobase_include_HEADERS+= libmemcached-1.2/get.h | 34 | nobase_include_HEADERS+= libmemcached-1.2/get.h |
44 | 35 | nobase_include_HEADERS+= libmemcached-1.2/hash.h | 35 | nobase_include_HEADERS+= libmemcached-1.2/hash.h |
45 | 36 | nobase_include_HEADERS+= libmemcached-1.2/isasl.h | ||
46 | 36 | nobase_include_HEADERS+= libmemcached-1.2/limits.h | 37 | nobase_include_HEADERS+= libmemcached-1.2/limits.h |
47 | 37 | nobase_include_HEADERS+= libmemcached-1.2/memcached.h | 38 | nobase_include_HEADERS+= libmemcached-1.2/memcached.h |
48 | 38 | nobase_include_HEADERS+= libmemcached-1.2/memcached.hpp | 39 | nobase_include_HEADERS+= libmemcached-1.2/memcached.hpp |
49 | 39 | 40 | ||
50 | === added file 'libmemcached-1.2/isasl.h' | |||
51 | --- libmemcached-1.2/isasl.h 1970-01-01 00:00:00 +0000 | |||
52 | +++ libmemcached-1.2/isasl.h 2014-06-20 23:47:25 +0000 | |||
53 | @@ -0,0 +1,92 @@ | |||
54 | 1 | /* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */ | ||
55 | 2 | /* | ||
56 | 3 | * Copyright (C) 2010 Membase, Inc | ||
57 | 4 | * All rights reserved. | ||
58 | 5 | * | ||
59 | 6 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
60 | 7 | * you may not use this file except in compliance with the License. | ||
61 | 8 | * You may obtain a copy of the License at | ||
62 | 9 | * | ||
63 | 10 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
64 | 11 | * | ||
65 | 12 | * Unless required by applicable law or agreed to in writing, software | ||
66 | 13 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
67 | 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
68 | 15 | * See the License for the specific language governing permissions and | ||
69 | 16 | * limitations under the License. | ||
70 | 17 | */ | ||
71 | 18 | |||
72 | 19 | /* This is a minimalistic SASL implementation */ | ||
73 | 20 | #ifndef SASL_ISASL_H | ||
74 | 21 | #define SASL_ISASL_H | ||
75 | 22 | |||
76 | 23 | #include "visibility.h" | ||
77 | 24 | |||
78 | 25 | #ifdef __cplusplus | ||
79 | 26 | extern "C" { | ||
80 | 27 | #endif | ||
81 | 28 | |||
82 | 29 | typedef struct { | ||
83 | 30 | unsigned long len; | ||
84 | 31 | unsigned char data[1]; | ||
85 | 32 | } sasl_secret_t; | ||
86 | 33 | |||
87 | 34 | typedef struct { | ||
88 | 35 | unsigned long id; | ||
89 | 36 | int (*proc)(void); | ||
90 | 37 | void *context; | ||
91 | 38 | } sasl_callback_t; | ||
92 | 39 | |||
93 | 40 | /* define the different callback id's we support */ | ||
94 | 41 | #define SASL_CB_USER 1 | ||
95 | 42 | #define SASL_CB_AUTHNAME 2 | ||
96 | 43 | #define SASL_CB_PASS 3 | ||
97 | 44 | #define SASL_CB_LIST_END 4 | ||
98 | 45 | |||
99 | 46 | /* Define the error codes we support */ | ||
100 | 47 | #define SASL_OK 0 | ||
101 | 48 | #define SASL_CONTINUE 1 | ||
102 | 49 | #define SASL_ERROR -1 | ||
103 | 50 | #define SASL_BADPARAM -7 | ||
104 | 51 | |||
105 | 52 | typedef struct sasl_conn sasl_conn_t; | ||
106 | 53 | |||
107 | 54 | LIBMEMCACHED_LOCAL | ||
108 | 55 | int sasl_client_init(const sasl_callback_t *callbacks); | ||
109 | 56 | |||
110 | 57 | LIBMEMCACHED_LOCAL | ||
111 | 58 | void sasl_done(void); | ||
112 | 59 | |||
113 | 60 | LIBMEMCACHED_LOCAL | ||
114 | 61 | int sasl_client_new(const char *service, | ||
115 | 62 | const char *serverFQDN, | ||
116 | 63 | const char *iplocalport, | ||
117 | 64 | const char *ipremoteport, | ||
118 | 65 | const sasl_callback_t *prompt_supp, | ||
119 | 66 | unsigned int flags, | ||
120 | 67 | sasl_conn_t **pconn); | ||
121 | 68 | |||
122 | 69 | LIBMEMCACHED_LOCAL | ||
123 | 70 | void sasl_dispose(sasl_conn_t **pconn); | ||
124 | 71 | |||
125 | 72 | LIBMEMCACHED_LOCAL | ||
126 | 73 | int sasl_client_start(sasl_conn_t *conn, | ||
127 | 74 | const char *mechlist, | ||
128 | 75 | void **prompt_need, | ||
129 | 76 | const char **clientout, | ||
130 | 77 | unsigned int *clientoutlen, | ||
131 | 78 | const char **mech); | ||
132 | 79 | |||
133 | 80 | LIBMEMCACHED_LOCAL | ||
134 | 81 | int sasl_client_step(sasl_conn_t *a, const void *b, unsigned int c, | ||
135 | 82 | void *d, const void *e, void *f); | ||
136 | 83 | |||
137 | 84 | LIBMEMCACHED_LOCAL | ||
138 | 85 | const char *sasl_errstring(int saslerr, | ||
139 | 86 | const char *langlist, | ||
140 | 87 | const char **outlang); | ||
141 | 88 | #ifdef __cplusplus | ||
142 | 89 | } | ||
143 | 90 | #endif | ||
144 | 91 | |||
145 | 92 | #endif | ||
146 | 0 | 93 | ||
147 | === modified file 'libmemcached-1.2/sasl.h' | |||
148 | --- libmemcached-1.2/sasl.h 2013-06-12 08:17:31 +0000 | |||
149 | +++ libmemcached-1.2/sasl.h 2014-06-20 23:47:25 +0000 | |||
150 | @@ -37,11 +37,7 @@ | |||
151 | 37 | 37 | ||
152 | 38 | #pragma once | 38 | #pragma once |
153 | 39 | 39 | ||
159 | 40 | #if defined(LIBMEMCACHED_WITH_SASL_SUPPORT) && LIBMEMCACHED_WITH_SASL_SUPPORT | 40 | #include <libmemcached-1.2/isasl.h> |
155 | 41 | # include <sasl/sasl.h> | ||
156 | 42 | #else | ||
157 | 43 | # define sasl_callback_t void | ||
158 | 44 | #endif | ||
160 | 45 | 41 | ||
161 | 46 | #ifdef __cplusplus | 42 | #ifdef __cplusplus |
162 | 47 | extern "C" { | 43 | extern "C" { |
163 | 48 | 44 | ||
164 | === modified file 'libmemcached-1.2/struct/sasl.h' | |||
165 | --- libmemcached-1.2/struct/sasl.h 2011-12-12 16:59:07 +0000 | |||
166 | +++ libmemcached-1.2/struct/sasl.h 2014-06-20 23:47:25 +0000 | |||
167 | @@ -35,14 +35,10 @@ | |||
168 | 35 | * | 35 | * |
169 | 36 | */ | 36 | */ |
170 | 37 | 37 | ||
171 | 38 | #if defined(LIBMEMCACHED_WITH_SASL_SUPPORT) && LIBMEMCACHED_WITH_SASL_SUPPORT | ||
172 | 39 | #include <sasl/sasl.h> | ||
173 | 40 | #else | ||
174 | 41 | #define sasl_callback_t void | ||
175 | 42 | #endif | ||
176 | 43 | |||
177 | 44 | #pragma once | 38 | #pragma once |
178 | 45 | 39 | ||
179 | 40 | #include <libmemcached-1.2/isasl.h> | ||
180 | 41 | |||
181 | 46 | struct memcached_sasl_st { | 42 | struct memcached_sasl_st { |
182 | 47 | sasl_callback_t *callbacks; | 43 | sasl_callback_t *callbacks; |
183 | 48 | /* | 44 | /* |
184 | 49 | 45 | ||
185 | === modified file 'libmemcached/include.am' | |||
186 | --- libmemcached/include.am 2014-02-03 15:21:04 +0000 | |||
187 | +++ libmemcached/include.am 2014-06-20 23:47:25 +0000 | |||
188 | @@ -107,6 +107,7 @@ | |||
189 | 107 | libmemcached_libmemcached_la_SOURCES+= libmemcached/response.cc | 107 | libmemcached_libmemcached_la_SOURCES+= libmemcached/response.cc |
190 | 108 | libmemcached_libmemcached_la_SOURCES+= libmemcached/result.cc | 108 | libmemcached_libmemcached_la_SOURCES+= libmemcached/result.cc |
191 | 109 | libmemcached_libmemcached_la_SOURCES+= libmemcached/sasl.cc | 109 | libmemcached_libmemcached_la_SOURCES+= libmemcached/sasl.cc |
192 | 110 | libmemcached_libmemcached_la_SOURCES+= libmemcached/sasl_client.cc | ||
193 | 110 | libmemcached_libmemcached_la_SOURCES+= libmemcached/server.cc | 111 | libmemcached_libmemcached_la_SOURCES+= libmemcached/server.cc |
194 | 111 | libmemcached_libmemcached_la_SOURCES+= libmemcached/server_list.cc | 112 | libmemcached_libmemcached_la_SOURCES+= libmemcached/server_list.cc |
195 | 112 | libmemcached_libmemcached_la_SOURCES+= libmemcached/server_list.hpp | 113 | libmemcached_libmemcached_la_SOURCES+= libmemcached/server_list.hpp |
196 | 113 | 114 | ||
197 | === modified file 'libmemcached/sasl.cc' | |||
198 | --- libmemcached/sasl.cc 2013-06-12 09:23:02 +0000 | |||
199 | +++ libmemcached/sasl.cc 2014-06-20 23:47:25 +0000 | |||
200 | @@ -36,112 +36,25 @@ | |||
201 | 36 | */ | 36 | */ |
202 | 37 | 37 | ||
203 | 38 | #include "libmemcached/common.h" | 38 | #include "libmemcached/common.h" |
204 | 39 | |||
205 | 39 | #include <cassert> | 40 | #include <cassert> |
206 | 40 | |||
207 | 41 | #if defined(LIBMEMCACHED_WITH_SASL_SUPPORT) && LIBMEMCACHED_WITH_SASL_SUPPORT | ||
208 | 42 | |||
209 | 43 | #if defined(HAVE_LIBSASL) && HAVE_LIBSASL | ||
210 | 44 | #include <sasl/sasl.h> | ||
211 | 45 | #endif | ||
212 | 46 | |||
213 | 47 | #include <pthread.h> | 41 | #include <pthread.h> |
214 | 48 | 42 | ||
215 | 49 | void memcached_set_sasl_callbacks(memcached_st *shell, | 43 | void memcached_set_sasl_callbacks(memcached_st *shell, |
216 | 50 | const sasl_callback_t *callbacks) | 44 | const sasl_callback_t *callbacks) |
217 | 51 | { | 45 | { |
224 | 52 | Memcached* self= memcached2Memcached(shell); | 46 | (void)shell; |
225 | 53 | if (self) | 47 | (void)callbacks; |
220 | 54 | { | ||
221 | 55 | self->sasl.callbacks= const_cast<sasl_callback_t *>(callbacks); | ||
222 | 56 | self->sasl.is_allocated= false; | ||
223 | 57 | } | ||
226 | 58 | } | 48 | } |
227 | 59 | 49 | ||
228 | 60 | sasl_callback_t *memcached_get_sasl_callbacks(memcached_st *shell) | 50 | sasl_callback_t *memcached_get_sasl_callbacks(memcached_st *shell) |
229 | 61 | { | 51 | { |
236 | 62 | Memcached* self= memcached2Memcached(shell); | 52 | (void)shell; |
231 | 63 | if (self) | ||
232 | 64 | { | ||
233 | 65 | return self->sasl.callbacks; | ||
234 | 66 | } | ||
235 | 67 | |||
237 | 68 | return NULL; | 53 | return NULL; |
238 | 69 | } | 54 | } |
239 | 70 | 55 | ||
240 | 71 | /** | ||
241 | 72 | * Resolve the names for both ends of a connection | ||
242 | 73 | * @param fd socket to check | ||
243 | 74 | * @param laddr local address (out) | ||
244 | 75 | * @param raddr remote address (out) | ||
245 | 76 | * @return true on success false otherwise (errno contains more info) | ||
246 | 77 | */ | ||
247 | 78 | static memcached_return_t resolve_names(memcached_instance_st& server, char *laddr, size_t laddr_length, char *raddr, size_t raddr_length) | ||
248 | 79 | { | ||
249 | 80 | char host[MEMCACHED_NI_MAXHOST]; | ||
250 | 81 | char port[MEMCACHED_NI_MAXSERV]; | ||
251 | 82 | struct sockaddr_storage saddr; | ||
252 | 83 | socklen_t salen= sizeof(saddr); | ||
253 | 84 | |||
254 | 85 | if (getsockname(server.fd, (struct sockaddr *)&saddr, &salen) < 0) | ||
255 | 86 | { | ||
256 | 87 | return memcached_set_error(server, MEMCACHED_HOST_LOOKUP_FAILURE, MEMCACHED_AT); | ||
257 | 88 | } | ||
258 | 89 | |||
259 | 90 | if (getnameinfo((struct sockaddr *)&saddr, salen, host, sizeof(host), port, sizeof(port), NI_NUMERICHOST | NI_NUMERICSERV) < 0) | ||
260 | 91 | { | ||
261 | 92 | return memcached_set_error(server, MEMCACHED_HOST_LOOKUP_FAILURE, MEMCACHED_AT); | ||
262 | 93 | } | ||
263 | 94 | |||
264 | 95 | (void)snprintf(laddr, laddr_length, "%s;%s", host, port); | ||
265 | 96 | salen= sizeof(saddr); | ||
266 | 97 | |||
267 | 98 | if (getpeername(server.fd, (struct sockaddr *)&saddr, &salen) < 0) | ||
268 | 99 | { | ||
269 | 100 | return memcached_set_error(server, MEMCACHED_HOST_LOOKUP_FAILURE, MEMCACHED_AT); | ||
270 | 101 | } | ||
271 | 102 | |||
272 | 103 | if (getnameinfo((struct sockaddr *)&saddr, salen, host, sizeof(host), | ||
273 | 104 | port, sizeof(port), NI_NUMERICHOST | NI_NUMERICSERV) < 0) | ||
274 | 105 | { | ||
275 | 106 | return memcached_set_error(server, MEMCACHED_HOST_LOOKUP_FAILURE, MEMCACHED_AT); | ||
276 | 107 | } | ||
277 | 108 | |||
278 | 109 | (void)snprintf(raddr, raddr_length, "%s;%s", host, port); | ||
279 | 110 | |||
280 | 111 | return MEMCACHED_SUCCESS; | ||
281 | 112 | } | ||
282 | 113 | |||
283 | 114 | extern "C" { | ||
284 | 115 | |||
285 | 116 | static void sasl_shutdown_function() | ||
286 | 117 | { | ||
287 | 118 | sasl_done(); | ||
288 | 119 | } | ||
289 | 120 | |||
290 | 121 | static volatile int sasl_startup_state= SASL_OK; | ||
291 | 122 | pthread_mutex_t sasl_startup_state_LOCK= PTHREAD_MUTEX_INITIALIZER; | ||
292 | 123 | static pthread_once_t sasl_startup_once= PTHREAD_ONCE_INIT; | ||
293 | 124 | static void sasl_startup_function(void) | ||
294 | 125 | { | ||
295 | 126 | sasl_startup_state= sasl_client_init(NULL); | ||
296 | 127 | |||
297 | 128 | if (sasl_startup_state == SASL_OK) | ||
298 | 129 | { | ||
299 | 130 | (void)atexit(sasl_shutdown_function); | ||
300 | 131 | } | ||
301 | 132 | } | ||
302 | 133 | |||
303 | 134 | } // extern "C" | ||
304 | 135 | |||
305 | 136 | memcached_return_t memcached_sasl_authenticate_connection(memcached_instance_st* server) | 56 | memcached_return_t memcached_sasl_authenticate_connection(memcached_instance_st* server) |
306 | 137 | { | 57 | { |
307 | 138 | #if defined(LIBMEMCACHED_WITH_SASL_SUPPORT) && LIBMEMCACHED_WITH_SASL_SUPPORT == 0 | ||
308 | 139 | if (LIBMEMCACHED_WITH_SASL_SUPPORT == 0) | ||
309 | 140 | { | ||
310 | 141 | return MEMCACHED_NOT_SUPPORTED; | ||
311 | 142 | } | ||
312 | 143 | #endif | ||
313 | 144 | |||
314 | 145 | if (server == NULL) | 58 | if (server == NULL) |
315 | 146 | { | 59 | { |
316 | 147 | return MEMCACHED_INVALID_ARGUMENTS; | 60 | return MEMCACHED_INVALID_ARGUMENTS; |
317 | @@ -150,14 +63,15 @@ | |||
318 | 150 | /* SANITY CHECK: SASL can only be used with the binary protocol */ | 63 | /* SANITY CHECK: SASL can only be used with the binary protocol */ |
319 | 151 | if (memcached_is_binary(server->root) == false) | 64 | if (memcached_is_binary(server->root) == false) |
320 | 152 | { | 65 | { |
323 | 153 | return memcached_set_error(*server, MEMCACHED_INVALID_ARGUMENTS, MEMCACHED_AT, | 66 | return memcached_set_error(*server, MEMCACHED_INVALID_ARGUMENTS, MEMCACHED_AT, |
324 | 154 | memcached_literal_param("memcached_sasl_authenticate_connection() is not supported via the ASCII protocol")); | 67 | memcached_literal_param("memcached_sasl_authenticate_connection() is " |
325 | 68 | "not supported via the ASCII protocol")); | ||
326 | 155 | } | 69 | } |
327 | 156 | 70 | ||
328 | 157 | /* Try to get the supported mech from the server. Servers without SASL | 71 | /* Try to get the supported mech from the server. Servers without SASL |
332 | 158 | * support will return UNKNOWN COMMAND, so we can just treat that | 72 | * support will return UNKNOWN COMMAND, so we can just treat that as |
333 | 159 | * as authenticated | 73 | * authenticated |
334 | 160 | */ | 74 | */ |
335 | 161 | protocol_binary_request_no_extras request= { }; | 75 | protocol_binary_request_no_extras request= { }; |
336 | 162 | 76 | ||
337 | 163 | initialize_binary_request(server, request.message.header); | 77 | initialize_binary_request(server, request.message.header); |
338 | @@ -183,7 +97,7 @@ | |||
339 | 183 | * that the server don't support SASL and treat it as success and | 97 | * that the server don't support SASL and treat it as success and |
340 | 184 | * let the client fail with the next operation if the error was | 98 | * let the client fail with the next operation if the error was |
341 | 185 | * caused by another problem.... | 99 | * caused by another problem.... |
343 | 186 | */ | 100 | */ |
344 | 187 | rc= MEMCACHED_SUCCESS; | 101 | rc= MEMCACHED_SUCCESS; |
345 | 188 | } | 102 | } |
346 | 189 | 103 | ||
347 | @@ -191,33 +105,9 @@ | |||
348 | 191 | } | 105 | } |
349 | 192 | assert_msg(server->fd != INVALID_SOCKET, "Programmer error, invalid socket"); | 106 | assert_msg(server->fd != INVALID_SOCKET, "Programmer error, invalid socket"); |
350 | 193 | 107 | ||
351 | 194 | /* set ip addresses */ | ||
352 | 195 | char laddr[MEMCACHED_NI_MAXHOST + MEMCACHED_NI_MAXSERV]; | ||
353 | 196 | char raddr[MEMCACHED_NI_MAXHOST + MEMCACHED_NI_MAXSERV]; | ||
354 | 197 | |||
355 | 198 | if (memcached_failed(rc= resolve_names(*server, laddr, sizeof(laddr), raddr, sizeof(raddr)))) | ||
356 | 199 | { | ||
357 | 200 | return rc; | ||
358 | 201 | } | ||
359 | 202 | |||
360 | 203 | int pthread_error; | ||
361 | 204 | if ((pthread_error= pthread_once(&sasl_startup_once, sasl_startup_function)) != 0) | ||
362 | 205 | { | ||
363 | 206 | return memcached_set_errno(*server, pthread_error, MEMCACHED_AT); | ||
364 | 207 | } | ||
365 | 208 | |||
366 | 209 | (void)pthread_mutex_lock(&sasl_startup_state_LOCK); | ||
367 | 210 | if (sasl_startup_state != SASL_OK) | ||
368 | 211 | { | ||
369 | 212 | const char *sasl_error_msg= sasl_errstring(sasl_startup_state, NULL, NULL); | ||
370 | 213 | return memcached_set_error(*server, MEMCACHED_AUTH_PROBLEM, MEMCACHED_AT, | ||
371 | 214 | memcached_string_make_from_cstr(sasl_error_msg)); | ||
372 | 215 | } | ||
373 | 216 | (void)pthread_mutex_unlock(&sasl_startup_state_LOCK); | ||
374 | 217 | |||
375 | 218 | sasl_conn_t *conn; | 108 | sasl_conn_t *conn; |
376 | 219 | int ret; | 109 | int ret; |
378 | 220 | if ((ret= sasl_client_new("memcached", server->_hostname, laddr, raddr, server->root->sasl.callbacks, 0, &conn) ) != SASL_OK) | 110 | if ((ret= sasl_client_new("memcached", NULL, NULL, NULL, server->root->sasl.callbacks, 0, &conn) ) != SASL_OK) |
379 | 221 | { | 111 | { |
380 | 222 | const char *sasl_error_msg= sasl_errstring(ret, NULL, NULL); | 112 | const char *sasl_error_msg= sasl_errstring(ret, NULL, NULL); |
381 | 223 | 113 | ||
382 | @@ -326,228 +216,109 @@ | |||
383 | 326 | const char *username, | 216 | const char *username, |
384 | 327 | const char *password) | 217 | const char *password) |
385 | 328 | { | 218 | { |
438 | 329 | if (libmemcached_has_feature(LIBMEMCACHED_FEATURE_HAS_SASL)) | 219 | Memcached* ptr= memcached2Memcached(shell); |
439 | 330 | { | 220 | |
440 | 331 | Memcached* ptr= memcached2Memcached(shell); | 221 | if (ptr == NULL or username == NULL or password == NULL) |
441 | 332 | 222 | { | |
442 | 333 | if (ptr == NULL or username == NULL or password == NULL) | 223 | return MEMCACHED_INVALID_ARGUMENTS; |
443 | 334 | { | 224 | } |
444 | 335 | return MEMCACHED_INVALID_ARGUMENTS; | 225 | |
445 | 336 | } | 226 | memcached_return_t ret; |
446 | 337 | 227 | if (memcached_failed(ret= memcached_behavior_set(ptr, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1))) | |
447 | 338 | memcached_return_t ret; | 228 | { |
448 | 339 | if (memcached_failed(ret= memcached_behavior_set(ptr, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1))) | 229 | return memcached_set_error(*ptr, ret, MEMCACHED_AT, memcached_literal_param("Unable change to binary protocol which is required for SASL.")); |
449 | 340 | { | 230 | } |
450 | 341 | return memcached_set_error(*ptr, ret, MEMCACHED_AT, memcached_literal_param("Unable change to binary protocol which is required for SASL.")); | 231 | |
451 | 342 | } | 232 | memcached_destroy_sasl_auth_data(ptr); |
452 | 343 | 233 | ||
453 | 344 | memcached_destroy_sasl_auth_data(ptr); | 234 | sasl_callback_t *callbacks= libmemcached_xcalloc(ptr, 4, sasl_callback_t); |
454 | 345 | 235 | size_t password_length= strlen(password); | |
455 | 346 | sasl_callback_t *callbacks= libmemcached_xcalloc(ptr, 4, sasl_callback_t); | 236 | size_t username_length= strlen(username); |
456 | 347 | size_t password_length= strlen(password); | 237 | char *name= (char *)libmemcached_malloc(ptr, username_length +1); |
457 | 348 | size_t username_length= strlen(username); | 238 | sasl_secret_t *secret= (sasl_secret_t*)libmemcached_malloc(ptr, password_length +1 + sizeof(sasl_secret_t)); |
458 | 349 | char *name= (char *)libmemcached_malloc(ptr, username_length +1); | 239 | |
459 | 350 | sasl_secret_t *secret= (sasl_secret_t*)libmemcached_malloc(ptr, password_length +1 + sizeof(sasl_secret_t)); | 240 | if (callbacks == NULL or name == NULL or secret == NULL) |
460 | 351 | 241 | { | |
461 | 352 | if (callbacks == NULL or name == NULL or secret == NULL) | 242 | libmemcached_free(ptr, callbacks); |
462 | 353 | { | 243 | libmemcached_free(ptr, name); |
463 | 354 | libmemcached_free(ptr, callbacks); | 244 | libmemcached_free(ptr, secret); |
464 | 355 | libmemcached_free(ptr, name); | 245 | return memcached_set_error(*ptr, MEMCACHED_MEMORY_ALLOCATION_FAILURE, MEMCACHED_AT); |
465 | 356 | libmemcached_free(ptr, secret); | 246 | } |
466 | 357 | return memcached_set_error(*ptr, MEMCACHED_MEMORY_ALLOCATION_FAILURE, MEMCACHED_AT); | 247 | |
467 | 358 | } | 248 | secret->len= password_length; |
468 | 359 | 249 | memcpy(secret->data, password, password_length); | |
469 | 360 | secret->len= password_length; | 250 | secret->data[password_length]= 0; |
470 | 361 | memcpy(secret->data, password, password_length); | 251 | |
471 | 362 | secret->data[password_length]= 0; | 252 | callbacks[0].id= SASL_CB_USER; |
472 | 363 | 253 | callbacks[0].proc= (int (*)())get_username; | |
473 | 364 | callbacks[0].id= SASL_CB_USER; | 254 | callbacks[0].context= strncpy(name, username, username_length +1); |
474 | 365 | callbacks[0].proc= (int (*)())get_username; | 255 | callbacks[1].id= SASL_CB_AUTHNAME; |
475 | 366 | callbacks[0].context= strncpy(name, username, username_length +1); | 256 | callbacks[1].proc= (int (*)())get_username; |
476 | 367 | callbacks[1].id= SASL_CB_AUTHNAME; | 257 | callbacks[1].context= name; |
477 | 368 | callbacks[1].proc= (int (*)())get_username; | 258 | callbacks[2].id= SASL_CB_PASS; |
478 | 369 | callbacks[1].context= name; | 259 | callbacks[2].proc= (int (*)())get_password; |
479 | 370 | callbacks[2].id= SASL_CB_PASS; | 260 | callbacks[2].context= secret; |
480 | 371 | callbacks[2].proc= (int (*)())get_password; | 261 | callbacks[3].id= SASL_CB_LIST_END; |
481 | 372 | callbacks[2].context= secret; | 262 | |
482 | 373 | callbacks[3].id= SASL_CB_LIST_END; | 263 | ptr->sasl.callbacks= callbacks; |
483 | 374 | 264 | ptr->sasl.is_allocated= true; | |
484 | 375 | ptr->sasl.callbacks= callbacks; | 265 | |
485 | 376 | ptr->sasl.is_allocated= true; | 266 | return MEMCACHED_SUCCESS; |
434 | 377 | |||
435 | 378 | return MEMCACHED_SUCCESS; | ||
436 | 379 | } | ||
437 | 380 | return MEMCACHED_NOT_SUPPORTED; | ||
486 | 381 | } | 267 | } |
487 | 382 | 268 | ||
488 | 383 | memcached_return_t memcached_destroy_sasl_auth_data(memcached_st *shell) | 269 | memcached_return_t memcached_destroy_sasl_auth_data(memcached_st *shell) |
489 | 384 | { | 270 | { |
513 | 385 | if (libmemcached_has_feature(LIBMEMCACHED_FEATURE_HAS_SASL)) | 271 | Memcached* ptr= memcached2Memcached(shell); |
514 | 386 | { | 272 | if (ptr == NULL) |
515 | 387 | Memcached* ptr= memcached2Memcached(shell); | 273 | { |
516 | 388 | if (ptr == NULL) | 274 | return MEMCACHED_INVALID_ARGUMENTS; |
517 | 389 | { | 275 | } |
518 | 390 | return MEMCACHED_INVALID_ARGUMENTS; | 276 | |
519 | 391 | } | 277 | if (ptr->sasl.callbacks == NULL) |
520 | 392 | 278 | { | |
498 | 393 | if (ptr->sasl.callbacks == NULL) | ||
499 | 394 | { | ||
500 | 395 | return MEMCACHED_SUCCESS; | ||
501 | 396 | } | ||
502 | 397 | |||
503 | 398 | if (ptr->sasl.is_allocated) | ||
504 | 399 | { | ||
505 | 400 | libmemcached_free(ptr, ptr->sasl.callbacks[0].context); | ||
506 | 401 | libmemcached_free(ptr, ptr->sasl.callbacks[2].context); | ||
507 | 402 | libmemcached_free(ptr, (void*)ptr->sasl.callbacks); | ||
508 | 403 | ptr->sasl.is_allocated= false; | ||
509 | 404 | } | ||
510 | 405 | |||
511 | 406 | ptr->sasl.callbacks= NULL; | ||
512 | 407 | |||
521 | 408 | return MEMCACHED_SUCCESS; | 279 | return MEMCACHED_SUCCESS; |
522 | 409 | } | 280 | } |
523 | 410 | 281 | ||
525 | 411 | return MEMCACHED_NOT_SUPPORTED; | 282 | if (ptr->sasl.is_allocated) |
526 | 283 | { | ||
527 | 284 | libmemcached_free(ptr, ptr->sasl.callbacks[0].context); | ||
528 | 285 | libmemcached_free(ptr, ptr->sasl.callbacks[2].context); | ||
529 | 286 | libmemcached_free(ptr, (void*)ptr->sasl.callbacks); | ||
530 | 287 | ptr->sasl.is_allocated= false; | ||
531 | 288 | } | ||
532 | 289 | |||
533 | 290 | ptr->sasl.callbacks= NULL; | ||
534 | 291 | |||
535 | 292 | return MEMCACHED_SUCCESS; | ||
536 | 412 | } | 293 | } |
537 | 413 | 294 | ||
538 | 414 | memcached_return_t memcached_clone_sasl(memcached_st *clone, const memcached_st *source) | 295 | memcached_return_t memcached_clone_sasl(memcached_st *clone, const memcached_st *source) |
539 | 415 | { | 296 | { |
640 | 416 | if (libmemcached_has_feature(LIBMEMCACHED_FEATURE_HAS_SASL)) | 297 | if (clone == NULL or source == NULL) |
641 | 417 | { | 298 | { |
642 | 418 | if (clone == NULL or source == NULL) | 299 | return MEMCACHED_INVALID_ARGUMENTS; |
643 | 419 | { | 300 | } |
644 | 420 | return MEMCACHED_INVALID_ARGUMENTS; | 301 | |
645 | 421 | } | 302 | if (source->sasl.callbacks == NULL) |
646 | 422 | 303 | { | |
547 | 423 | if (source->sasl.callbacks == NULL) | ||
548 | 424 | { | ||
549 | 425 | return MEMCACHED_SUCCESS; | ||
550 | 426 | } | ||
551 | 427 | |||
552 | 428 | /* Hopefully we are using our own callback mechanisms.. */ | ||
553 | 429 | if (source->sasl.callbacks[0].id == SASL_CB_USER && | ||
554 | 430 | source->sasl.callbacks[0].proc == (int (*)())get_username && | ||
555 | 431 | source->sasl.callbacks[1].id == SASL_CB_AUTHNAME && | ||
556 | 432 | source->sasl.callbacks[1].proc == (int (*)())get_username && | ||
557 | 433 | source->sasl.callbacks[2].id == SASL_CB_PASS && | ||
558 | 434 | source->sasl.callbacks[2].proc == (int (*)())get_password && | ||
559 | 435 | source->sasl.callbacks[3].id == SASL_CB_LIST_END) | ||
560 | 436 | { | ||
561 | 437 | sasl_secret_t *secret= (sasl_secret_t *)source->sasl.callbacks[2].context; | ||
562 | 438 | return memcached_set_sasl_auth_data(clone, | ||
563 | 439 | (const char*)source->sasl.callbacks[0].context, | ||
564 | 440 | (const char*)secret->data); | ||
565 | 441 | } | ||
566 | 442 | |||
567 | 443 | /* | ||
568 | 444 | * But we're not. It may work if we know what the user tries to pass | ||
569 | 445 | * into the list, but if we don't know the ID we don't know how to handle | ||
570 | 446 | * the context... | ||
571 | 447 | */ | ||
572 | 448 | ptrdiff_t total= 0; | ||
573 | 449 | |||
574 | 450 | while (source->sasl.callbacks[total].id != SASL_CB_LIST_END) | ||
575 | 451 | { | ||
576 | 452 | switch (source->sasl.callbacks[total].id) | ||
577 | 453 | { | ||
578 | 454 | case SASL_CB_USER: | ||
579 | 455 | case SASL_CB_AUTHNAME: | ||
580 | 456 | case SASL_CB_PASS: | ||
581 | 457 | break; | ||
582 | 458 | default: | ||
583 | 459 | /* I don't know how to deal with this... */ | ||
584 | 460 | return MEMCACHED_NOT_SUPPORTED; | ||
585 | 461 | } | ||
586 | 462 | |||
587 | 463 | ++total; | ||
588 | 464 | } | ||
589 | 465 | |||
590 | 466 | sasl_callback_t *callbacks= libmemcached_xcalloc(clone, total +1, sasl_callback_t); | ||
591 | 467 | if (callbacks == NULL) | ||
592 | 468 | { | ||
593 | 469 | return MEMCACHED_MEMORY_ALLOCATION_FAILURE; | ||
594 | 470 | } | ||
595 | 471 | memcpy(callbacks, source->sasl.callbacks, (total + 1) * sizeof(sasl_callback_t)); | ||
596 | 472 | |||
597 | 473 | /* Now update the context... */ | ||
598 | 474 | for (ptrdiff_t x= 0; x < total; ++x) | ||
599 | 475 | { | ||
600 | 476 | if (callbacks[x].id == SASL_CB_USER || callbacks[x].id == SASL_CB_AUTHNAME) | ||
601 | 477 | { | ||
602 | 478 | callbacks[x].context= (sasl_callback_t*)libmemcached_malloc(clone, strlen((const char*)source->sasl.callbacks[x].context)); | ||
603 | 479 | |||
604 | 480 | if (callbacks[x].context == NULL) | ||
605 | 481 | { | ||
606 | 482 | /* Failed to allocate memory, clean up previously allocated memory */ | ||
607 | 483 | for (ptrdiff_t y= 0; y < x; ++y) | ||
608 | 484 | { | ||
609 | 485 | libmemcached_free(clone, clone->sasl.callbacks[y].context); | ||
610 | 486 | } | ||
611 | 487 | |||
612 | 488 | libmemcached_free(clone, callbacks); | ||
613 | 489 | return MEMCACHED_MEMORY_ALLOCATION_FAILURE; | ||
614 | 490 | } | ||
615 | 491 | strncpy((char*)callbacks[x].context, (const char*)source->sasl.callbacks[x].context, sizeof(callbacks[x].context)); | ||
616 | 492 | } | ||
617 | 493 | else | ||
618 | 494 | { | ||
619 | 495 | sasl_secret_t *src= (sasl_secret_t *)source->sasl.callbacks[x].context; | ||
620 | 496 | sasl_secret_t *n= (sasl_secret_t*)libmemcached_malloc(clone, src->len + 1 + sizeof(*n)); | ||
621 | 497 | if (n == NULL) | ||
622 | 498 | { | ||
623 | 499 | /* Failed to allocate memory, clean up previously allocated memory */ | ||
624 | 500 | for (ptrdiff_t y= 0; y < x; ++y) | ||
625 | 501 | { | ||
626 | 502 | libmemcached_free(clone, clone->sasl.callbacks[y].context); | ||
627 | 503 | } | ||
628 | 504 | |||
629 | 505 | libmemcached_free(clone, callbacks); | ||
630 | 506 | return MEMCACHED_MEMORY_ALLOCATION_FAILURE; | ||
631 | 507 | } | ||
632 | 508 | memcpy(n, src, src->len + 1 + sizeof(*n)); | ||
633 | 509 | callbacks[x].context= n; | ||
634 | 510 | } | ||
635 | 511 | } | ||
636 | 512 | |||
637 | 513 | clone->sasl.callbacks= callbacks; | ||
638 | 514 | clone->sasl.is_allocated= true; | ||
639 | 515 | |||
647 | 516 | return MEMCACHED_SUCCESS; | 304 | return MEMCACHED_SUCCESS; |
648 | 517 | } | 305 | } |
649 | 518 | 306 | ||
685 | 519 | return MEMCACHED_NOT_SUPPORTED; | 307 | /* Only support using our own callback mechanisms.. */ |
686 | 520 | } | 308 | if (source->sasl.callbacks[0].id == SASL_CB_USER && |
687 | 521 | 309 | source->sasl.callbacks[0].proc == (int (*)())get_username && | |
688 | 522 | #else | 310 | source->sasl.callbacks[1].id == SASL_CB_AUTHNAME && |
689 | 523 | 311 | source->sasl.callbacks[1].proc == (int (*)())get_username && | |
690 | 524 | void memcached_set_sasl_callbacks(memcached_st *, const sasl_callback_t *) | 312 | source->sasl.callbacks[2].id == SASL_CB_PASS && |
691 | 525 | { | 313 | source->sasl.callbacks[2].proc == (int (*)())get_password && |
692 | 526 | } | 314 | source->sasl.callbacks[3].id == SASL_CB_LIST_END) |
693 | 527 | 315 | { | |
694 | 528 | sasl_callback_t *memcached_get_sasl_callbacks(memcached_st *) | 316 | sasl_secret_t *secret= (sasl_secret_t *)source->sasl.callbacks[2].context; |
695 | 529 | { | 317 | return memcached_set_sasl_auth_data(clone, |
696 | 530 | return NULL; | 318 | (const char*)source->sasl.callbacks[0].context, |
697 | 531 | } | 319 | (const char*)secret->data); |
698 | 532 | 320 | } | |
699 | 533 | memcached_return_t memcached_set_sasl_auth_data(memcached_st *, const char *, const char *) | 321 | |
700 | 534 | { | 322 | return MEMCACHED_NOT_SUPPORTED; |
701 | 535 | return MEMCACHED_NOT_SUPPORTED; | 323 | } |
702 | 536 | } | 324 | |
668 | 537 | |||
669 | 538 | memcached_return_t memcached_clone_sasl(memcached_st *, const memcached_st *) | ||
670 | 539 | { | ||
671 | 540 | return MEMCACHED_NOT_SUPPORTED; | ||
672 | 541 | } | ||
673 | 542 | |||
674 | 543 | memcached_return_t memcached_destroy_sasl_auth_data(memcached_st*) | ||
675 | 544 | { | ||
676 | 545 | return MEMCACHED_NOT_SUPPORTED; | ||
677 | 546 | } | ||
678 | 547 | |||
679 | 548 | memcached_return_t memcached_sasl_authenticate_connection(memcached_instance_st*) | ||
680 | 549 | { | ||
681 | 550 | return MEMCACHED_NOT_SUPPORTED; | ||
682 | 551 | } | ||
683 | 552 | |||
684 | 553 | #endif | ||
703 | 554 | 325 | ||
704 | === added file 'libmemcached/sasl_client.cc' | |||
705 | --- libmemcached/sasl_client.cc 1970-01-01 00:00:00 +0000 | |||
706 | +++ libmemcached/sasl_client.cc 2014-06-20 23:47:25 +0000 | |||
707 | @@ -0,0 +1,192 @@ | |||
708 | 1 | /* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */ | ||
709 | 2 | /* | ||
710 | 3 | * Copyright (C) 2010 Membase, Inc | ||
711 | 4 | * All rights reserved. | ||
712 | 5 | * | ||
713 | 6 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
714 | 7 | * you may not use this file except in compliance with the License. | ||
715 | 8 | * You may obtain a copy of the License at | ||
716 | 9 | * | ||
717 | 10 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
718 | 11 | * | ||
719 | 12 | * Unless required by applicable law or agreed to in writing, software | ||
720 | 13 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
721 | 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
722 | 15 | * See the License for the specific language governing permissions and | ||
723 | 16 | * limitations under the License. | ||
724 | 17 | */ | ||
725 | 18 | |||
726 | 19 | // Minimal SASL client that only supports PLAIN authentication. | ||
727 | 20 | |||
728 | 21 | #include <libmemcached-1.2/isasl.h> | ||
729 | 22 | #include <string.h> | ||
730 | 23 | #include <stdlib.h> | ||
731 | 24 | |||
732 | 25 | struct sasl_conn { | ||
733 | 26 | const sasl_callback_t *callbacks; | ||
734 | 27 | char *userdata; | ||
735 | 28 | }; | ||
736 | 29 | |||
737 | 30 | static const char *plain = "PLAIN"; | ||
738 | 31 | |||
739 | 32 | LIBMEMCACHED_LOCAL | ||
740 | 33 | int sasl_client_new(const char *service, | ||
741 | 34 | const char *serverFQDN, | ||
742 | 35 | const char *iplocalport, | ||
743 | 36 | const char *ipremoteport, | ||
744 | 37 | const sasl_callback_t *prompt_supp, | ||
745 | 38 | unsigned flags, | ||
746 | 39 | sasl_conn_t **pconn) | ||
747 | 40 | { | ||
748 | 41 | struct sasl_conn *conn = (sasl_conn *) calloc(1, sizeof(*conn)); | ||
749 | 42 | if (conn == NULL) { | ||
750 | 43 | return SASL_ERROR; | ||
751 | 44 | } | ||
752 | 45 | |||
753 | 46 | conn->callbacks = prompt_supp; | ||
754 | 47 | *pconn = conn; | ||
755 | 48 | |||
756 | 49 | (void)service; | ||
757 | 50 | (void)serverFQDN; | ||
758 | 51 | (void)iplocalport; | ||
759 | 52 | (void)ipremoteport; | ||
760 | 53 | (void)flags; | ||
761 | 54 | |||
762 | 55 | return SASL_OK; | ||
763 | 56 | } | ||
764 | 57 | |||
765 | 58 | LIBMEMCACHED_LOCAL | ||
766 | 59 | void sasl_dispose(sasl_conn_t **pconn) { | ||
767 | 60 | free((*pconn)->userdata); | ||
768 | 61 | free(*pconn); | ||
769 | 62 | *pconn = NULL; | ||
770 | 63 | } | ||
771 | 64 | |||
772 | 65 | LIBMEMCACHED_LOCAL | ||
773 | 66 | int sasl_client_start(sasl_conn_t *conn, | ||
774 | 67 | const char *mechlist, | ||
775 | 68 | void **prompt_need, | ||
776 | 69 | const char **clientout, | ||
777 | 70 | unsigned int*clientoutlen, | ||
778 | 71 | const char **mech) { | ||
779 | 72 | const char *usernm = NULL; | ||
780 | 73 | unsigned int usernmlen; | ||
781 | 74 | int i = 0; | ||
782 | 75 | int found = 0; | ||
783 | 76 | sasl_secret_t *pass; | ||
784 | 77 | |||
785 | 78 | if (strstr(mechlist, "PLAIN") == NULL) { | ||
786 | 79 | return SASL_ERROR; | ||
787 | 80 | } | ||
788 | 81 | |||
789 | 82 | *mech = plain; | ||
790 | 83 | |||
791 | 84 | /* get the username: */ | ||
792 | 85 | while (conn->callbacks[i].id != SASL_CB_LIST_END) { | ||
793 | 86 | if (conn->callbacks[i].id == SASL_CB_USER) { | ||
794 | 87 | int r; | ||
795 | 88 | union { | ||
796 | 89 | int (*get)(void*, int, const char **, unsigned int*); | ||
797 | 90 | int (*proc)(void); | ||
798 | 91 | } hack; | ||
799 | 92 | |||
800 | 93 | hack.proc = conn->callbacks[i].proc; | ||
801 | 94 | |||
802 | 95 | r = hack.get(conn->callbacks[i].context, SASL_CB_USER, | ||
803 | 96 | &usernm, &usernmlen); | ||
804 | 97 | if (r != SASL_OK) { | ||
805 | 98 | return r; | ||
806 | 99 | } | ||
807 | 100 | found = 1; | ||
808 | 101 | break; | ||
809 | 102 | } | ||
810 | 103 | ++i; | ||
811 | 104 | } | ||
812 | 105 | |||
813 | 106 | if (!found) { | ||
814 | 107 | return SASL_ERROR; | ||
815 | 108 | } | ||
816 | 109 | |||
817 | 110 | found = 0; | ||
818 | 111 | i = 0; | ||
819 | 112 | while (conn->callbacks[i].id != SASL_CB_LIST_END) { | ||
820 | 113 | if (conn->callbacks[i].id == SASL_CB_PASS) { | ||
821 | 114 | int r; | ||
822 | 115 | union { | ||
823 | 116 | int (*get)(sasl_conn_t *, void *, int, sasl_secret_t **); | ||
824 | 117 | int (*proc)(void); | ||
825 | 118 | } hack; | ||
826 | 119 | |||
827 | 120 | hack.proc = conn->callbacks[i].proc; | ||
828 | 121 | |||
829 | 122 | r = hack.get(conn, conn->callbacks[i].context, SASL_CB_PASS, | ||
830 | 123 | &pass); | ||
831 | 124 | if (r != SASL_OK) { | ||
832 | 125 | return r; | ||
833 | 126 | } | ||
834 | 127 | found = 1; | ||
835 | 128 | break; | ||
836 | 129 | } | ||
837 | 130 | ++i; | ||
838 | 131 | } | ||
839 | 132 | if (!found) { | ||
840 | 133 | return SASL_ERROR; | ||
841 | 134 | } | ||
842 | 135 | |||
843 | 136 | conn->userdata = (char *) calloc(usernmlen + 1 + pass->len + 1, 1); | ||
844 | 137 | if (conn->userdata == NULL) { | ||
845 | 138 | return SASL_ERROR; | ||
846 | 139 | } | ||
847 | 140 | |||
848 | 141 | memcpy(conn->userdata + 1, usernm, usernmlen); | ||
849 | 142 | memcpy(conn->userdata + usernmlen + 2, pass->data, pass->len); | ||
850 | 143 | *clientout = conn->userdata; | ||
851 | 144 | *clientoutlen = (unsigned int)(usernmlen + 2 + pass->len); | ||
852 | 145 | |||
853 | 146 | (void)prompt_need; | ||
854 | 147 | return SASL_OK; | ||
855 | 148 | } | ||
856 | 149 | |||
857 | 150 | LIBMEMCACHED_LOCAL | ||
858 | 151 | void sasl_done(void) | ||
859 | 152 | { | ||
860 | 153 | |||
861 | 154 | } | ||
862 | 155 | |||
863 | 156 | LIBMEMCACHED_LOCAL | ||
864 | 157 | int sasl_client_step(sasl_conn_t *a, const void *b, unsigned int c, | ||
865 | 158 | void *d, const void *e, void *f) | ||
866 | 159 | { | ||
867 | 160 | (void)a;(void)b;(void)c;(void)d;(void)e;(void)f; | ||
868 | 161 | return SASL_ERROR; | ||
869 | 162 | } | ||
870 | 163 | |||
871 | 164 | LIBMEMCACHED_LOCAL | ||
872 | 165 | int sasl_client_init(const sasl_callback_t *callbacks) | ||
873 | 166 | { | ||
874 | 167 | (void)callbacks; | ||
875 | 168 | return SASL_OK; | ||
876 | 169 | } | ||
877 | 170 | |||
878 | 171 | LIBMEMCACHED_LOCAL | ||
879 | 172 | const char *sasl_errstring(int saslerr, | ||
880 | 173 | const char *langlist, | ||
881 | 174 | const char **outlang) | ||
882 | 175 | { | ||
883 | 176 | (void)langlist; | ||
884 | 177 | |||
885 | 178 | if (outlang) | ||
886 | 179 | { | ||
887 | 180 | *outlang= "en-us"; | ||
888 | 181 | } | ||
889 | 182 | |||
890 | 183 | switch(saslerr) | ||
891 | 184 | { | ||
892 | 185 | case SASL_OK: return "successful result"; | ||
893 | 186 | case SASL_CONTINUE: return "another step is needed in authentication"; | ||
894 | 187 | case SASL_ERROR: return "generic failure"; | ||
895 | 188 | case SASL_BADPARAM: return "invalid parameter supplied"; | ||
896 | 189 | default: return "undefined error!"; | ||
897 | 190 | } | ||
898 | 191 | } | ||
899 | 192 |
Any update on this?