1 /* cfmglue.c
2 by Rolf Braun, for CMU SASL on Mac OS X
3
4 This file provides routines to allow CFM (os 9 linkage) Carbon applications
5 to use the native Mach-O SASL libraries on Mac OS X, using CFBundle to
6 load the backend libraries and automatically allocated assembly callbacks
7 $Id: cfmglue.c,v 1.4 2003/06/12 00:33:05 rbraun Exp $
8 */
9 /*
10 * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 *
16 * 1. Redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer.
18 *
19 * 2. Redistributions in binary form must reproduce the above copyright
20 * notice, this list of conditions and the following disclaimer in
21 * the documentation and/or other materials provided with the
22 * distribution.
23 *
24 * 3. The name "Carnegie Mellon University" must not be used to
25 * endorse or promote products derived from this software without
26 * prior written permission. For permission or any other legal
27 * details, please contact
28 * Office of Technology Transfer
29 * Carnegie Mellon University
30 * 5000 Forbes Avenue
31 * Pittsburgh, PA 15213-3890
32 * (412) 268-4387, fax: (412) 268-7395
33 * tech-transfer@andrew.cmu.edu
34 *
35 * 4. Redistributions of any form whatsoever must retain the following
36 * acknowledgment:
37 * "This product includes software developed by Computing Services
38 * at Carnegie Mellon University (http://www.cmu.edu/computing/)."
39 *
40 * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
41 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
42 * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
43 * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
44 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
45 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
46 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
47 */
48
49 #include <Carbon.h>
50 #include <string.h>
51 #include <stdlib.h>
52 #include "sasl.h"
53 #include "saslutil.h"
54 #include "prop.h"
55
56 /* prototypes for internal functions (from saslint.h) */
57 int _sasl_add_string(char **out, int *alloclen, int *outlen, const char *add);
58 int _buf_alloc(char **rwbuf, unsigned *curlen, unsigned newlen);
59 void _sasl_get_errorbuf(sasl_conn_t *conn, char ***bufhdl, unsigned **lenhdl);
60
61 void *MachOFunctionPointerForCFMFunctionPointer( void *cfmfp );
62 sasl_callback_t *GetCFMCallbacks(const sasl_callback_t *callbacks);
63 void DisposeCFMCallbacks(sasl_callback_t *callbacks);
64
65 int _cfmsasl_haveCustomAlloc = 0;
66 int _cfmsasl_haveCustomMutex = 0;
67 int _cfmsasl_initted = 0;
68
69 /* DO NOT change the order of this struct! It MUST match that
70 of the iovec struct in /usr/include/sys/uio.h on Mac OS X!
71 It MUST also match that of the Mac OS 9 Carbon config.h since
72 Carbon CFM stuff links at runtime against whatever it's running on! */
73 struct iovec {
74 char *iov_base;
75 long iov_len;
76 };
77
78 typedef struct
79 {
80 CFURLRef bundleURL;
81 CFBundleRef myBundle;
82 sasl_callback_t *clientCallbacks;
83 sasl_callback_t *serverCallbacks;
84 int (*SASLClientNewPtr)(const char *service,
85 const char *serverFQDN,
86 const char *iplocalport,
87 const char *ipremoteport,
88 const sasl_callback_t *prompt_supp,
89 unsigned flags,
90 sasl_conn_t **pconn);
91 int (*SASLClientStartPtr)(sasl_conn_t *conn,
92 const char *mechlist,
93 sasl_interact_t **prompt_need,
94 const char **clientout,
95 unsigned *clientoutlen,
96 const char **mech);
97 int (*SASLClientStepPtr)(sasl_conn_t *conn,
98 const char *serverin,
99 unsigned serverinlen,
100 sasl_interact_t **prompt_need,
101 const char **clientout,
102 unsigned *clientoutlen);
103 const char * (*SASLErrStringPtr)(int saslerr,
104 const char *langlist,
105 const char **outlang);
106 const char *(*sasl_errdetailPtr)(sasl_conn_t *conn);
107 int (*SASLGetPropPtr)(sasl_conn_t *conn, int propnum, const void **pvalue);
108 int (*SASLSetPropPtr)(sasl_conn_t *conn,
109 int propnum,
110 const void *value);
111 int (*SASLIdlePtr)(sasl_conn_t *conn);
112 int (*SASLEncodePtr)(sasl_conn_t *conn,
113 const char *input, unsigned inputlen,
114 const char **output, unsigned *outputlen);
115 int (*SASLDecodePtr)(sasl_conn_t *conn,
116 const char *input, unsigned inputlen,
117 const char **output, unsigned *outputlen);
118 int (*SASLEncodeVPtr)(sasl_conn_t *conn,
119 const struct iovec *invec, unsigned numiov,
120 const char **output, unsigned *outputlen);
121 int (*SASLDisposePtr)(sasl_conn_t **pconn);
122 int (*SASLDonePtr)();
123 void (*SASLSetAllocPtr)(sasl_malloc_t *, sasl_calloc_t *, sasl_realloc_t *, sasl_free_t *);
124 int (*sasl_decode64Ptr)(const char *in, unsigned inlen,
125 char *out, unsigned outmax, unsigned *outlen);
126 int (*sasl_encode64Ptr)(const char *in, unsigned inlen,
127 char *out, unsigned outmax, unsigned *outlen);
128 int (*sasl_mkchalPtr)(sasl_conn_t *conn, char *buf,
129 unsigned maxlen, unsigned hostflag);
130 int (*sasl_utf8verifyPtr)(const char *str, unsigned len);
131 void (*sasl_churnPtr)(sasl_rand_t *rpool,
132 const char *data,
133 unsigned len);
134 void (*sasl_randPtr)(sasl_rand_t *rpool,
135 char *buf,
136 unsigned len);
137 void (*sasl_randseedPtr)(sasl_rand_t *rpool,
138 const char *seed,
139 unsigned len);
140 void (*sasl_randfreePtr)(sasl_rand_t **rpool);
141 int (*sasl_randcreatePtr)(sasl_rand_t **rpool);
142 void (*SASLSetMutexPtr)(sasl_mutex_alloc_t *mn, sasl_mutex_lock_t *ml,
143 sasl_mutex_unlock_t *mu, sasl_mutex_free_t *md);
144 int (*SASLServerNewPtr)(const char *service,
145 const char *serverFQDN,
146 const char *user_realm,
147 const char *iplocalport,
148 const char *ipremoteport,
149 const sasl_callback_t *callbacks,
150 unsigned flags,
151 sasl_conn_t **pconn);
152 int (*sasl_listmechPtr)(sasl_conn_t *conn,
153 const char *user,
154 const char *prefix,
155 const char *sep,
156 const char *suffix,
157 const char **result,
158 unsigned *plen,
159 int *pcount);
160 int (*SASLServerStartPtr)(sasl_conn_t *conn,
161 const char *mech,
162 const char *clientin,
163 unsigned clientinlen,
164 const char **serverout,
165 unsigned *serveroutlen);
166 int (*SASLServerStepPtr)(sasl_conn_t *conn,
167 const char *clientin,
168 unsigned clientinlen,
169 const char **serverout,
170 unsigned *serveroutlen);
171 int (*sasl_checkpassPtr)(sasl_conn_t *conn,
172 const char *user,
173 unsigned userlen,
174 const char *pass,
175 unsigned passlen);
176 int (*sasl_user_existsPtr)(sasl_conn_t *conn,
177 const char *service,
178 const char *user_realm,
179 const char *user);
180 int (*sasl_setpassPtr)(sasl_conn_t *conn,
181 const char *user,
182 const char *pass,
183 unsigned passlen,
184 const char *oldpass, unsigned oldpasslen,
185 unsigned flags);
186 int (*sasl_checkapopPtr)(sasl_conn_t *conn,
187 const char *challenge, unsigned challen,
188 const char *response, unsigned resplen);
189 int (*sasl_auxprop_requestPtr)(sasl_conn_t *conn,
190 const char **propnames);
191 struct propctx *(*sasl_auxprop_getctxPtr)(sasl_conn_t *conn);
192 void (*sasl_erasebufferPtr)(char *pass, unsigned len);
193 struct propctx *(*prop_newPtr)(unsigned estimate);
194 int (*prop_dupPtr)(struct propctx *src_ctx, struct propctx **dst_ctx);
195 const struct propval *(*prop_getPtr)(struct propctx *ctx);
196 int (*prop_getnamesPtr)(struct propctx *ctx, const char **names,
197 struct propval *vals);
198 void (*prop_clearPtr)(struct propctx *ctx, int requests);
199 void (*prop_erasePtr)(struct propctx *ctx, const char *name);
200 void (*prop_disposePtr)(struct propctx **ctx);
201 int (*prop_formatPtr)(struct propctx *ctx, const char *sep, int seplen,
202 char *outbuf, unsigned outmax, unsigned *outlen);
203 int (*prop_setPtr)(struct propctx *ctx, const char *name,
204 const char *value, int vallen);
205 int (*prop_setvalsPtr)(struct propctx *ctx, const char *name,
206 const char **values);
207 int (*_sasl_add_stringPtr)(char **out, int *alloclen, int *outlen, const char *add);
208 int (*_buf_allocPtr)(char **rwbuf, unsigned *curlen, unsigned newlen);
209 void (*_sasl_get_errorbufPtr)(sasl_conn_t *conn, char ***bufhdl, unsigned **lenhdl);
210
211 } GlobalsRec;
212
213 typedef struct
214 {
215 sasl_malloc_t *custMalloc;
216 sasl_calloc_t *custCalloc;
217 sasl_realloc_t *custRealloc;
218 sasl_free_t *custFree;
219
220 sasl_mutex_alloc_t *custMutexNew;
221 sasl_mutex_lock_t *custMutexLock;
222 sasl_mutex_unlock_t *custMutexUnlock;
223 sasl_mutex_free_t *custMutexDispose;
224 } GlobalParamsRec;
225
226 typedef struct
227 {
228 sasl_conn_t *ctx;
229 sasl_callback_t *cbk;
230 } cfm_sasl_conn_t;
231
232 GlobalsRec saslcfmglob; // The globals
233 GlobalParamsRec saslcfmglobp;
234
235 // From Apple sample code... (CarbonLib SDK, CFM->MachO->CFM)
236 //
237 // This function allocates a block of CFM glue code which contains the instructions to call CFM routines
238 //
MachOFunctionPointerForCFMFunctionPointer(void * cfmfp)239 void *MachOFunctionPointerForCFMFunctionPointer( void *cfmfp )
240 {
241 UInt32 template[6] = {0x3D800000, 0x618C0000, 0x800C0000, 0x804C0004, 0x7C0903A6, 0x4E800420};
242 UInt32 *mfp = (UInt32*) NewPtr( sizeof(template) ); // Must later dispose of allocated memory
243 mfp[0] = template[0] | ((UInt32)cfmfp >> 16);
244 mfp[1] = template[1] | ((UInt32)cfmfp & 0xFFFF);
245 mfp[2] = template[2];
246 mfp[3] = template[3];
247 mfp[4] = template[4];
248 mfp[5] = template[5];
249 MakeDataExecutable( mfp, sizeof(template) );
250 return( mfp );
251 }
252
GetCFMCallbacks(const sasl_callback_t * callbacks)253 sasl_callback_t *GetCFMCallbacks(const sasl_callback_t *callbacks)
254 {
255 int cbksize = 0;
256 const sasl_callback_t *cbk = callbacks;
257 sasl_callback_t *ncbk, *new_callbacks;
258 while (cbk->id) {
259 cbksize++; cbk++;
260 }
261 cbksize++; cbk = callbacks;
262
263 ncbk = new_callbacks = (sasl_callback_t *)NewPtr(cbksize * sizeof(sasl_callback_t));
264 if (!ncbk) return nil;
265 while (cbksize--) {
266 ncbk->id = cbk->id;
267 ncbk->context = cbk->context;
268 if (cbk->proc)
269 ncbk->proc = MachOFunctionPointerForCFMFunctionPointer(cbk->proc);
270 else ncbk->proc = nil;
271 ncbk++; cbk++;
272 }
273 return new_callbacks;
274 }
275
DisposeCFMCallbacks(sasl_callback_t * callbacks)276 void DisposeCFMCallbacks(sasl_callback_t *callbacks)
277 {
278 sasl_callback_t *cbk = callbacks;
279 if (!cbk) return;
280 while (cbk->id) {
281 if (cbk->proc) DisposePtr((Ptr)cbk->proc);
282 cbk++;
283 }
284 DisposePtr((Ptr)callbacks);
285 }
286
287 int _cfmsasl_common_init(const sasl_callback_t *callbacks, int isServer, const char *appname);
288
_cfmsasl_common_init(const sasl_callback_t * callbacks,int isServer,const char * appname)289 int _cfmsasl_common_init(const sasl_callback_t *callbacks, int isServer, const char *appname)
290 {
291 int (*SASLClientInitPtr)(const sasl_callback_t *callbacks);
292 int (*SASLServerInitPtr)(const sasl_callback_t *callbacks, const char *appname);
293 int result = SASL_NOMEM;
294
295 if (!_cfmsasl_initted) {
296 // The skeleton for this code originally came from the CFM->MachO->CFM sample
297 // provided by Aple with the Carbon SDK. It shows how to use CFBundle to call MachO
298 // libraries from CFM and how to encapsulate callbacks into CFM.
299 memset( &saslcfmglob, 0, sizeof(GlobalsRec) ); // Initialize the globals
300
301 // Make a CFURLRef from the CFString representation of the bundle's path.
302 // See the Core Foundation URL Services chapter for details.
303 saslcfmglob.bundleURL = CFURLCreateWithFileSystemPath(
304 nil, // workaround for Radar # 2452789
305 CFSTR("/Library/Frameworks/SASL2.framework"), // hard coded path for sample
306 0,
307 true );
308 if ( saslcfmglob.bundleURL != NULL )
309
310 // Make a bundle instance using the URLRef.
311 saslcfmglob.myBundle = CFBundleCreate(
312 NULL /* kCFAllocatorDefault */, // workaround for Radar # 2452789
313 saslcfmglob.bundleURL );
314
315 if ( saslcfmglob.myBundle && CFBundleLoadExecutable( saslcfmglob.myBundle )) { // Try to load the executable from my bundle.
316
317 // Now that the code is loaded, search for the functions we want by name.
318 saslcfmglob.SASLClientNewPtr = (void*)CFBundleGetFunctionPointerForName(
319 saslcfmglob.myBundle, CFSTR("sasl_client_new") );
320
321 saslcfmglob.SASLClientStartPtr = (void*)CFBundleGetFunctionPointerForName(
322 saslcfmglob.myBundle, CFSTR("sasl_client_start") );
323
324 saslcfmglob.SASLClientStepPtr = (void*)CFBundleGetFunctionPointerForName(
325 saslcfmglob.myBundle, CFSTR("sasl_client_step") );
326
327 saslcfmglob.SASLErrStringPtr = (void*)CFBundleGetFunctionPointerForName(
328 saslcfmglob.myBundle, CFSTR("sasl_errstring") );
329
330 saslcfmglob.sasl_errdetailPtr = (void*)CFBundleGetFunctionPointerForName(
331 saslcfmglob.myBundle, CFSTR("sasl_errdetail") );
332
333 saslcfmglob.SASLGetPropPtr = (void*)CFBundleGetFunctionPointerForName(
334 saslcfmglob.myBundle, CFSTR("sasl_getprop") );
335
336 saslcfmglob.SASLSetPropPtr = (void*)CFBundleGetFunctionPointerForName(
337 saslcfmglob.myBundle, CFSTR("sasl_setprop") );
338
339 saslcfmglob.SASLIdlePtr = (void*)CFBundleGetFunctionPointerForName(
340 saslcfmglob.myBundle, CFSTR("sasl_idle") );
341
342 saslcfmglob.SASLEncodePtr = (void*)CFBundleGetFunctionPointerForName(
343 saslcfmglob.myBundle, CFSTR("sasl_encode") );
344
345 saslcfmglob.SASLEncodeVPtr = (void*)CFBundleGetFunctionPointerForName(
346 saslcfmglob.myBundle, CFSTR("sasl_encodev") );
347
348 saslcfmglob.SASLDecodePtr = (void*)CFBundleGetFunctionPointerForName(
349 saslcfmglob.myBundle, CFSTR("sasl_decode") );
350
351 saslcfmglob.SASLDisposePtr = (void*)CFBundleGetFunctionPointerForName(
352 saslcfmglob.myBundle, CFSTR("sasl_dispose") );
353
354 saslcfmglob.SASLDonePtr = (void*)CFBundleGetFunctionPointerForName(
355 saslcfmglob.myBundle, CFSTR("sasl_done") );
356
357 saslcfmglob.SASLSetAllocPtr = (void*)CFBundleGetFunctionPointerForName(
358 saslcfmglob.myBundle, CFSTR("sasl_set_alloc") );
359
360 saslcfmglob.sasl_encode64Ptr = (void*)CFBundleGetFunctionPointerForName(
361 saslcfmglob.myBundle, CFSTR("sasl_encode64") );
362
363 saslcfmglob.sasl_decode64Ptr = (void*)CFBundleGetFunctionPointerForName(
364 saslcfmglob.myBundle, CFSTR("sasl_decode64") );
365
366 saslcfmglob.sasl_mkchalPtr = (void*)CFBundleGetFunctionPointerForName(
367 saslcfmglob.myBundle, CFSTR("sasl_mkchal") );
368
369 saslcfmglob.sasl_utf8verifyPtr = (void*)CFBundleGetFunctionPointerForName(
370 saslcfmglob.myBundle, CFSTR("sasl_utf8verify") );
371
372 saslcfmglob.sasl_churnPtr = (void*)CFBundleGetFunctionPointerForName(
373 saslcfmglob.myBundle, CFSTR("sasl_churn") );
374
375 saslcfmglob.sasl_randPtr = (void*)CFBundleGetFunctionPointerForName(
376 saslcfmglob.myBundle, CFSTR("sasl_rand") );
377
378 saslcfmglob.sasl_randseedPtr = (void*)CFBundleGetFunctionPointerForName(
379 saslcfmglob.myBundle, CFSTR("sasl_randseed") );
380
381 saslcfmglob.sasl_randcreatePtr = (void*)CFBundleGetFunctionPointerForName(
382 saslcfmglob.myBundle, CFSTR("sasl_randcreate") );
383
384 saslcfmglob.sasl_randfreePtr = (void*)CFBundleGetFunctionPointerForName(
385 saslcfmglob.myBundle, CFSTR("sasl_randfree") );
386
387 saslcfmglob.SASLSetMutexPtr = (void*)CFBundleGetFunctionPointerForName(
388 saslcfmglob.myBundle, CFSTR("sasl_set_mutex") );
389
390 saslcfmglob.SASLServerNewPtr = (void*)CFBundleGetFunctionPointerForName(
391 saslcfmglob.myBundle, CFSTR("sasl_server_new") );
392
393 saslcfmglob.SASLServerStartPtr = (void*)CFBundleGetFunctionPointerForName(
394 saslcfmglob.myBundle, CFSTR("sasl_server_start") );
395
396 saslcfmglob.SASLServerStepPtr = (void*)CFBundleGetFunctionPointerForName(
397 saslcfmglob.myBundle, CFSTR("sasl_server_step") );
398
399 saslcfmglob.sasl_listmechPtr = (void*)CFBundleGetFunctionPointerForName(
400 saslcfmglob.myBundle, CFSTR("sasl_listmech") );
401
402 saslcfmglob.sasl_checkpassPtr = (void*)CFBundleGetFunctionPointerForName(
403 saslcfmglob.myBundle, CFSTR("sasl_checkpass") );
404
405 saslcfmglob.sasl_setpassPtr = (void*)CFBundleGetFunctionPointerForName(
406 saslcfmglob.myBundle, CFSTR("sasl_setpass") );
407
408 saslcfmglob.sasl_user_existsPtr = (void*)CFBundleGetFunctionPointerForName(
409 saslcfmglob.myBundle, CFSTR("sasl_user_exists") );
410
411 saslcfmglob.sasl_checkapopPtr = (void*)CFBundleGetFunctionPointerForName(
412 saslcfmglob.myBundle, CFSTR("sasl_checkapop") );
413
414 saslcfmglob.sasl_auxprop_requestPtr = (void*)CFBundleGetFunctionPointerForName(
415 saslcfmglob.myBundle, CFSTR("sasl_auxprop_request") );
416
417 saslcfmglob.sasl_auxprop_getctxPtr = (void*)CFBundleGetFunctionPointerForName(
418 saslcfmglob.myBundle, CFSTR("sasl_auxprop_getctx") );
419
420 saslcfmglob.sasl_erasebufferPtr = (void*)CFBundleGetFunctionPointerForName(
421 saslcfmglob.myBundle, CFSTR("sasl_erasebuffer") );
422
423 saslcfmglob.prop_newPtr = (void*)CFBundleGetFunctionPointerForName(
424 saslcfmglob.myBundle, CFSTR("prop_new") );
425
426 saslcfmglob.prop_dupPtr = (void*)CFBundleGetFunctionPointerForName(
427 saslcfmglob.myBundle, CFSTR("prop_dup") );
428
429 saslcfmglob.prop_getPtr = (void*)CFBundleGetFunctionPointerForName(
430 saslcfmglob.myBundle, CFSTR("prop_get") );
431
432 saslcfmglob.prop_getnamesPtr = (void*)CFBundleGetFunctionPointerForName(
433 saslcfmglob.myBundle, CFSTR("prop_getnames") );
434
435 saslcfmglob.prop_clearPtr = (void*)CFBundleGetFunctionPointerForName(
436 saslcfmglob.myBundle, CFSTR("prop_clear") );
437
438 saslcfmglob.prop_erasePtr = (void*)CFBundleGetFunctionPointerForName(
439 saslcfmglob.myBundle, CFSTR("prop_erase") );
440
441 saslcfmglob.prop_disposePtr = (void*)CFBundleGetFunctionPointerForName(
442 saslcfmglob.myBundle, CFSTR("prop_dispose") );
443
444 saslcfmglob.prop_formatPtr = (void*)CFBundleGetFunctionPointerForName(
445 saslcfmglob.myBundle, CFSTR("prop_format") );
446
447 saslcfmglob.prop_setPtr = (void*)CFBundleGetFunctionPointerForName(
448 saslcfmglob.myBundle, CFSTR("prop_set") );
449
450 saslcfmglob.prop_setvalsPtr = (void*)CFBundleGetFunctionPointerForName(
451 saslcfmglob.myBundle, CFSTR("prop_setvals") );
452
453 /* These are internal functions used by our sasl_seterror */
454 saslcfmglob._sasl_add_stringPtr = (void*)CFBundleGetFunctionPointerForName(
455 saslcfmglob.myBundle, CFSTR("_sasl_add_string") );
456
457 saslcfmglob._buf_allocPtr = (void*)CFBundleGetFunctionPointerForName(
458 saslcfmglob.myBundle, CFSTR("_buf_alloc") );
459
460 saslcfmglob._sasl_get_errorbufPtr = (void*)CFBundleGetFunctionPointerForName(
461 saslcfmglob.myBundle, CFSTR("_sasl_get_errorbuf") );
462
463 if (!_cfmsasl_haveCustomAlloc) {
464 saslcfmglobp.custMalloc = MachOFunctionPointerForCFMFunctionPointer(malloc);
465 saslcfmglobp.custCalloc = MachOFunctionPointerForCFMFunctionPointer(calloc);
466 saslcfmglobp.custRealloc = MachOFunctionPointerForCFMFunctionPointer(realloc);
467 saslcfmglobp.custFree = MachOFunctionPointerForCFMFunctionPointer(free);
468
469 _cfmsasl_haveCustomAlloc = 1;
470 }
471
472 saslcfmglob.SASLSetAllocPtr(saslcfmglobp.custMalloc, saslcfmglobp.custCalloc,
473 saslcfmglobp.custRealloc, saslcfmglobp.custFree);
474
475 if (_cfmsasl_haveCustomMutex)
476 saslcfmglob.SASLSetMutexPtr(saslcfmglobp.custMutexNew, saslcfmglobp.custMutexLock,
477 saslcfmglobp.custMutexUnlock, saslcfmglobp.custMutexDispose);
478
479 } else if (saslcfmglob.myBundle) {
480 CFRelease(saslcfmglob.myBundle);
481 saslcfmglob.myBundle = nil;
482 }
483
484 if (saslcfmglob.bundleURL && !saslcfmglob.myBundle) {
485 CFRelease(saslcfmglob.bundleURL);
486 saslcfmglob.bundleURL = nil;
487 }
488
489 if (saslcfmglob.myBundle)
490 _cfmsasl_initted = 1;
491 }
492
493 if (_cfmsasl_initted) {
494 if (isServer) {
495 SASLServerInitPtr = (void*)CFBundleGetFunctionPointerForName(
496 saslcfmglob.myBundle, CFSTR("sasl_server_init") );
497 if (SASLServerInitPtr != nil) {
498 sasl_callback_t *new_callbacks = NULL;
499 if (callbacks)
500 new_callbacks = GetCFMCallbacks(callbacks);
501 result = SASLServerInitPtr(new_callbacks, appname);
502 saslcfmglob.serverCallbacks = new_callbacks;
503 }
504 } else {
505 SASLClientInitPtr = (void*)CFBundleGetFunctionPointerForName(
506 saslcfmglob.myBundle, CFSTR("sasl_client_init") );
507 if (SASLClientInitPtr != nil) {
508 sasl_callback_t *new_callbacks = NULL;
509 if (callbacks)
510 new_callbacks = GetCFMCallbacks(callbacks);
511 result = SASLClientInitPtr(new_callbacks);
512 saslcfmglob.clientCallbacks = new_callbacks;
513 }
514 }
515 }
516 return result;
517 }
518
sasl_server_init(const sasl_callback_t * callbacks,const char * appname)519 int sasl_server_init(const sasl_callback_t *callbacks,
520 const char *appname)
521 {
522 return _cfmsasl_common_init(callbacks, true, appname);
523 }
524
sasl_client_init(const sasl_callback_t * callbacks)525 int sasl_client_init(const sasl_callback_t *callbacks)
526 {
527 return _cfmsasl_common_init(callbacks, false, nil);
528 }
529
sasl_done(void)530 void sasl_done(void)
531 {
532 if (!_cfmsasl_initted)
533 return;
534 if (!saslcfmglob.SASLDonePtr) return;
535
536 saslcfmglob.SASLDonePtr();
537 DisposeCFMCallbacks(saslcfmglob.clientCallbacks);
538 DisposeCFMCallbacks(saslcfmglob.serverCallbacks);
539 CFBundleUnloadExecutable(saslcfmglob.myBundle);
540 CFRelease(saslcfmglob.myBundle);
541 CFRelease(saslcfmglob.bundleURL);
542 saslcfmglob.myBundle = NULL;
543 saslcfmglob.bundleURL = NULL;
544
545 _cfmsasl_initted = 0;
546 }
547
sasl_client_new(const char * service,const char * serverFQDN,const char * iplocalport,const char * ipremoteport,const sasl_callback_t * prompt_supp,unsigned flags,sasl_conn_t ** pconn)548 int sasl_client_new (const char *service,
549 const char *serverFQDN,
550 const char *iplocalport,
551 const char *ipremoteport,
552 const sasl_callback_t *prompt_supp,
553 unsigned flags,
554 sasl_conn_t **pconn)
555 {
556 sasl_callback_t *new_ps = NULL;
557 int result;
558 cfm_sasl_conn_t *myconn;
559
560 if (!_cfmsasl_initted)
561 return SASL_NOMEM;
562 if (!saslcfmglob.SASLClientNewPtr) return SASL_NOMEM;
563
564 if (prompt_supp)
565 new_ps = GetCFMCallbacks(prompt_supp);
566
567 // this is commented out because sasl.h incorrectly described the api
568 // if (*pconn)
569 // DisposeCFMCallbacks(((cfm_sasl_conn_t *)*pconn)->cbk);
570 // else {
571 myconn = (cfm_sasl_conn_t *) NewPtr(sizeof(cfm_sasl_conn_t));
572 if (myconn == NULL) {
573 return SASL_NOMEM;
574 }
575
576 myconn->ctx = NULL;
577 // }
578
579 result = saslcfmglob.SASLClientNewPtr(service, serverFQDN, iplocalport,
580 ipremoteport, new_ps, flags,
581 &(myconn->ctx));
582 myconn->cbk = new_ps;
583
584 *pconn = (sasl_conn_t *)myconn;
585
586 return result;
587 }
588
sasl_server_new(const char * service,const char * serverFQDN,const char * user_realm,const char * iplocalport,const char * ipremoteport,const sasl_callback_t * callbacks,unsigned flags,sasl_conn_t ** pconn)589 int sasl_server_new (const char *service,
590 const char *serverFQDN,
591 const char *user_realm,
592 const char *iplocalport,
593 const char *ipremoteport,
594 const sasl_callback_t *callbacks,
595 unsigned flags,
596 sasl_conn_t **pconn)
597 {
598 sasl_callback_t *new_ps = NULL;
599 int result;
600
601 if (!_cfmsasl_initted)
602 return SASL_NOMEM;
603 if (!saslcfmglob.SASLServerNewPtr) return SASL_NOMEM;
604
605 if (callbacks)
606 new_ps = GetCFMCallbacks(callbacks);
607 *pconn = (sasl_conn_t *)NewPtr(sizeof(cfm_sasl_conn_t));
608 ((cfm_sasl_conn_t *)*pconn)->ctx = nil;
609
610 result = saslcfmglob.SASLServerNewPtr(service, serverFQDN, user_realm,
611 iplocalport, ipremoteport, new_ps, flags,
612 &((cfm_sasl_conn_t *)*pconn)->ctx);
613 ((cfm_sasl_conn_t *)*pconn)->cbk = new_ps;
614
615 return result;
616 }
617
sasl_dispose(sasl_conn_t ** pconn)618 void sasl_dispose(sasl_conn_t **pconn)
619 {
620 if (!_cfmsasl_initted)
621 return;
622 if (!saslcfmglob.SASLDisposePtr) return;
623
624 if (!pconn) return;
625 if (!*pconn) return;
626
627 saslcfmglob.SASLDisposePtr(&((cfm_sasl_conn_t *)*pconn)->ctx);
628 DisposeCFMCallbacks(((cfm_sasl_conn_t *)*pconn)->cbk);
629 DisposePtr((Ptr)*pconn);
630 *pconn = NULL;
631 }
632
sasl_client_start(sasl_conn_t * conn,const char * mechlist,sasl_interact_t ** prompt_need,const char ** clientout,unsigned * clientoutlen,const char ** mech)633 int sasl_client_start (sasl_conn_t *conn,
634 const char *mechlist,
635 sasl_interact_t **prompt_need,
636 const char **clientout,
637 unsigned *clientoutlen,
638 const char **mech)
639 {
640 if (!_cfmsasl_initted)
641 return SASL_NOMEM;
642 if (!saslcfmglob.SASLClientStartPtr) return SASL_NOMEM;
643
644 return saslcfmglob.SASLClientStartPtr(((cfm_sasl_conn_t *)conn)->ctx, mechlist,
645 prompt_need, clientout, clientoutlen, mech);
646 }
647
sasl_client_step(sasl_conn_t * conn,const char * serverin,unsigned serverinlen,sasl_interact_t ** prompt_need,const char ** clientout,unsigned * clientoutlen)648 int sasl_client_step (sasl_conn_t *conn,
649 const char *serverin,
650 unsigned serverinlen,
651 sasl_interact_t **prompt_need,
652 const char **clientout,
653 unsigned *clientoutlen)
654 {
655 if (!_cfmsasl_initted)
656 return SASL_NOMEM;
657 if (!saslcfmglob.SASLClientStepPtr) return SASL_NOMEM;
658
659 return saslcfmglob.SASLClientStepPtr(((cfm_sasl_conn_t *)conn)->ctx, serverin,
660 serverinlen, prompt_need, clientout, clientoutlen);
661 }
662
sasl_errstring(int saslerr,const char * langlist,const char ** outlang)663 const char *sasl_errstring(int saslerr,
664 const char *langlist,
665 const char **outlang)
666 {
667 if (!_cfmsasl_initted)
668 return NULL;
669 if (!saslcfmglob.SASLErrStringPtr) return NULL;
670
671 return saslcfmglob.SASLErrStringPtr(saslerr, langlist, outlang);
672 }
673
sasl_errdetail(sasl_conn_t * conn)674 const char *sasl_errdetail(sasl_conn_t *conn)
675 {
676 if (!_cfmsasl_initted)
677 return NULL;
678 if (!saslcfmglob.sasl_errdetailPtr) return NULL;
679
680 return saslcfmglob.sasl_errdetailPtr(((cfm_sasl_conn_t *)conn)->ctx);
681 }
682
sasl_getprop(sasl_conn_t * conn,int propnum,const void ** pvalue)683 int sasl_getprop(sasl_conn_t *conn, int propnum, const void **pvalue)
684 {
685 if (!_cfmsasl_initted)
686 return SASL_NOMEM;
687 if (!saslcfmglob.SASLGetPropPtr) return SASL_NOMEM;
688
689 return saslcfmglob.SASLGetPropPtr(((cfm_sasl_conn_t *)conn)->ctx, propnum, pvalue);
690 }
691
sasl_setprop(sasl_conn_t * conn,int propnum,const void * value)692 int sasl_setprop(sasl_conn_t *conn,
693 int propnum,
694 const void *value)
695 {
696 if (!_cfmsasl_initted)
697 return SASL_NOMEM;
698 if (!saslcfmglob.SASLSetPropPtr) return SASL_NOMEM;
699
700 return saslcfmglob.SASLSetPropPtr(((cfm_sasl_conn_t *)conn)->ctx, propnum, value);
701 }
702
sasl_idle(sasl_conn_t * conn)703 int sasl_idle(sasl_conn_t *conn)
704 {
705 if (!_cfmsasl_initted)
706 return SASL_NOMEM;
707 if (!saslcfmglob.SASLIdlePtr) return SASL_NOMEM;
708
709 return saslcfmglob.SASLIdlePtr(((cfm_sasl_conn_t *)conn)->ctx);
710 }
711
sasl_encode(sasl_conn_t * conn,const char * input,unsigned inputlen,const char ** output,unsigned * outputlen)712 int sasl_encode(sasl_conn_t *conn,
713 const char *input, unsigned inputlen,
714 const char **output, unsigned *outputlen)
715 {
716 if (!_cfmsasl_initted)
717 return SASL_NOMEM;
718 if (!saslcfmglob.SASLEncodePtr) return SASL_NOMEM;
719
720 return saslcfmglob.SASLEncodePtr(((cfm_sasl_conn_t *)conn)->ctx, input, inputlen,
721 output, outputlen);
722 }
723
sasl_encodev(sasl_conn_t * conn,const struct iovec * invec,unsigned numiov,const char ** output,unsigned * outputlen)724 int sasl_encodev(sasl_conn_t *conn,
725 const struct iovec *invec, unsigned numiov,
726 const char **output, unsigned *outputlen)
727 {
728 if (!_cfmsasl_initted)
729 return SASL_NOMEM;
730 if (!saslcfmglob.SASLEncodeVPtr) return SASL_NOMEM;
731
732 return saslcfmglob.SASLEncodeVPtr(((cfm_sasl_conn_t *)conn)->ctx, invec, numiov,
733 output, outputlen);
734 }
735
sasl_decode(sasl_conn_t * conn,const char * input,unsigned inputlen,const char ** output,unsigned * outputlen)736 int sasl_decode(sasl_conn_t *conn,
737 const char *input, unsigned inputlen,
738 const char **output, unsigned *outputlen)
739 {
740 if (!_cfmsasl_initted)
741 return SASL_NOMEM;
742 if (!saslcfmglob.SASLDecodePtr) return SASL_NOMEM;
743
744 return saslcfmglob.SASLDecodePtr(((cfm_sasl_conn_t *)conn)->ctx, input, inputlen,
745 output, outputlen);
746 }
747
sasl_decode64(const char * in,unsigned inlen,char * out,unsigned outmax,unsigned * outlen)748 int sasl_decode64(const char *in, unsigned inlen,
749 char *out, unsigned outmax, unsigned *outlen)
750 {
751 if (!_cfmsasl_initted)
752 return SASL_NOMEM;
753 if (!saslcfmglob.sasl_decode64Ptr) return SASL_NOMEM;
754
755 return saslcfmglob.sasl_decode64Ptr(in, inlen, out, outmax, outlen);
756 }
757
sasl_encode64(const char * in,unsigned inlen,char * out,unsigned outmax,unsigned * outlen)758 int sasl_encode64(const char *in, unsigned inlen,
759 char *out, unsigned outmax, unsigned *outlen)
760 {
761 if (!_cfmsasl_initted)
762 return SASL_NOMEM;
763 if (!saslcfmglob.sasl_encode64Ptr) return SASL_NOMEM;
764
765 return saslcfmglob.sasl_encode64Ptr(in, inlen, out, outmax, outlen);
766 }
767
sasl_set_alloc(sasl_malloc_t * ma,sasl_calloc_t * ca,sasl_realloc_t * rea,sasl_free_t * fr)768 void sasl_set_alloc(sasl_malloc_t *ma, sasl_calloc_t *ca, sasl_realloc_t *rea, sasl_free_t *fr)
769 {
770 if (_cfmsasl_haveCustomAlloc) {
771 DisposePtr((Ptr)saslcfmglobp.custMalloc);
772 DisposePtr((Ptr)saslcfmglobp.custCalloc);
773 DisposePtr((Ptr)saslcfmglobp.custRealloc);
774 DisposePtr((Ptr)saslcfmglobp.custFree);
775 }
776 saslcfmglobp.custMalloc = MachOFunctionPointerForCFMFunctionPointer(ma);
777 saslcfmglobp.custCalloc = MachOFunctionPointerForCFMFunctionPointer(ca);
778 saslcfmglobp.custRealloc = MachOFunctionPointerForCFMFunctionPointer(rea);
779 saslcfmglobp.custFree = MachOFunctionPointerForCFMFunctionPointer(fr);
780 _cfmsasl_haveCustomAlloc = 1;
781 }
782
sasl_mkchal(sasl_conn_t * conn,char * buf,unsigned maxlen,unsigned hostflag)783 int sasl_mkchal(sasl_conn_t *conn, char *buf,
784 unsigned maxlen, unsigned hostflag)
785 {
786 if (!_cfmsasl_initted)
787 return SASL_NOMEM;
788 if (!saslcfmglob.sasl_mkchalPtr) return SASL_NOMEM;
789
790 return saslcfmglob.sasl_mkchalPtr(((cfm_sasl_conn_t *)conn)->ctx, buf, maxlen, hostflag);
791 }
792
sasl_utf8verify(const char * str,unsigned len)793 int sasl_utf8verify(const char *str, unsigned len)
794 {
795 if (!_cfmsasl_initted)
796 return SASL_NOMEM;
797 if (!saslcfmglob.sasl_utf8verifyPtr) return SASL_NOMEM;
798
799 return saslcfmglob.sasl_utf8verifyPtr(str, len);
800 }
801
sasl_churn(sasl_rand_t * rpool,const char * data,unsigned len)802 void sasl_churn(sasl_rand_t *rpool,
803 const char *data,
804 unsigned len)
805 {
806 if (!_cfmsasl_initted)
807 return;
808 if (!saslcfmglob.sasl_churnPtr) return;
809
810 saslcfmglob.sasl_churnPtr(rpool, data, len);
811 }
812
sasl_rand(sasl_rand_t * rpool,char * buf,unsigned len)813 void sasl_rand(sasl_rand_t *rpool,
814 char *buf,
815 unsigned len)
816 {
817 if (!_cfmsasl_initted)
818 return;
819 if (!saslcfmglob.sasl_randPtr) return;
820
821 saslcfmglob.sasl_randPtr(rpool, buf, len);
822 }
823
sasl_randseed(sasl_rand_t * rpool,const char * seed,unsigned len)824 void sasl_randseed(sasl_rand_t *rpool,
825 const char *seed,
826 unsigned len)
827 {
828 if (!_cfmsasl_initted)
829 return;
830 if (!saslcfmglob.sasl_randseedPtr) return;
831
832 saslcfmglob.sasl_randseedPtr(rpool, seed, len);
833 }
834
sasl_randfree(sasl_rand_t ** rpool)835 void sasl_randfree(sasl_rand_t **rpool)
836 {
837 if (!_cfmsasl_initted)
838 return;
839 if (!saslcfmglob.sasl_randfreePtr) return;
840
841 saslcfmglob.sasl_randfreePtr(rpool);
842 }
843
sasl_randcreate(sasl_rand_t ** rpool)844 int sasl_randcreate(sasl_rand_t **rpool)
845 {
846 if (!_cfmsasl_initted)
847 return SASL_NOMEM;
848 if (!saslcfmglob.sasl_randcreatePtr) return SASL_NOMEM;
849
850 return saslcfmglob.sasl_randcreatePtr(rpool);
851 }
852
sasl_set_mutex(sasl_mutex_alloc_t * mn,sasl_mutex_lock_t * ml,sasl_mutex_unlock_t * mu,sasl_mutex_free_t * md)853 void sasl_set_mutex(sasl_mutex_alloc_t *mn, sasl_mutex_lock_t *ml,
854 sasl_mutex_unlock_t *mu, sasl_mutex_free_t *md)
855 {
856 if (_cfmsasl_haveCustomMutex) {
857 DisposePtr((Ptr)saslcfmglobp.custMutexNew);
858 DisposePtr((Ptr)saslcfmglobp.custMutexLock);
859 DisposePtr((Ptr)saslcfmglobp.custMutexUnlock);
860 DisposePtr((Ptr)saslcfmglobp.custMutexDispose);
861 }
862 saslcfmglobp.custMutexNew = MachOFunctionPointerForCFMFunctionPointer(mn);
863 saslcfmglobp.custMutexLock = MachOFunctionPointerForCFMFunctionPointer(ml);
864 saslcfmglobp.custMutexUnlock = MachOFunctionPointerForCFMFunctionPointer(mu);
865 saslcfmglobp.custMutexDispose = MachOFunctionPointerForCFMFunctionPointer(md);
866 _cfmsasl_haveCustomMutex = 1;
867 }
868
sasl_listmech(sasl_conn_t * conn,const char * user,const char * prefix,const char * sep,const char * suffix,const char ** result,unsigned * plen,int * pcount)869 int sasl_listmech(sasl_conn_t *conn,
870 const char *user,
871 const char *prefix,
872 const char *sep,
873 const char *suffix,
874 const char **result,
875 unsigned *plen,
876 int *pcount)
877 {
878 if (!_cfmsasl_initted)
879 return SASL_NOMEM;
880 if (!saslcfmglob.sasl_listmechPtr) return SASL_NOMEM;
881
882 return saslcfmglob.sasl_listmechPtr(((cfm_sasl_conn_t *)conn)->ctx, user, prefix, sep,
883 suffix, result, plen, pcount);
884 }
885
sasl_server_start(sasl_conn_t * conn,const char * mech,const char * clientin,unsigned clientinlen,const char ** serverout,unsigned * serveroutlen)886 int sasl_server_start(sasl_conn_t *conn,
887 const char *mech,
888 const char *clientin,
889 unsigned clientinlen,
890 const char **serverout,
891 unsigned *serveroutlen)
892 {
893 if (!_cfmsasl_initted)
894 return SASL_NOMEM;
895 if (!saslcfmglob.SASLServerStartPtr) return SASL_NOMEM;
896
897 return saslcfmglob.SASLServerStartPtr(((cfm_sasl_conn_t *)conn)->ctx, mech, clientin,
898 clientinlen, serverout, serveroutlen);
899 }
900
sasl_server_step(sasl_conn_t * conn,const char * clientin,unsigned clientinlen,const char ** serverout,unsigned * serveroutlen)901 int sasl_server_step(sasl_conn_t *conn,
902 const char *clientin,
903 unsigned clientinlen,
904 const char **serverout,
905 unsigned *serveroutlen)
906 {
907 if (!_cfmsasl_initted)
908 return SASL_NOMEM;
909 if (!saslcfmglob.SASLServerStepPtr) return SASL_NOMEM;
910
911 return saslcfmglob.SASLServerStepPtr(((cfm_sasl_conn_t *)conn)->ctx, clientin, clientinlen,
912 serverout, serveroutlen);
913 }
914
sasl_checkpass(sasl_conn_t * conn,const char * user,unsigned userlen,const char * pass,unsigned passlen)915 int sasl_checkpass(sasl_conn_t *conn,
916 const char *user,
917 unsigned userlen,
918 const char *pass,
919 unsigned passlen)
920 {
921 if (!_cfmsasl_initted)
922 return SASL_NOMEM;
923 if (!saslcfmglob.sasl_checkpassPtr) return SASL_NOMEM;
924
925 return saslcfmglob.sasl_checkpassPtr(((cfm_sasl_conn_t *)conn)->ctx, user, userlen, pass,
926 passlen);
927 }
928
sasl_user_exists(sasl_conn_t * conn,const char * service,const char * user_realm,const char * user)929 int sasl_user_exists(sasl_conn_t *conn,
930 const char *service,
931 const char *user_realm,
932 const char *user)
933 {
934 if (!_cfmsasl_initted)
935 return SASL_NOMEM;
936 if (!saslcfmglob.sasl_user_existsPtr) return SASL_NOMEM;
937
938 return saslcfmglob.sasl_user_existsPtr(((cfm_sasl_conn_t *)conn)->ctx,
939 service, user_realm, user);
940 }
941
sasl_setpass(sasl_conn_t * conn,const char * user,const char * pass,unsigned passlen,const char * oldpass,unsigned oldpasslen,unsigned flags)942 int sasl_setpass(sasl_conn_t *conn,
943 const char *user,
944 const char *pass,
945 unsigned passlen,
946 const char *oldpass, unsigned oldpasslen,
947 unsigned flags)
948 {
949 if (!_cfmsasl_initted)
950 return SASL_NOMEM;
951 if (!saslcfmglob.sasl_setpassPtr) return SASL_NOMEM;
952
953 return saslcfmglob.sasl_setpassPtr(((cfm_sasl_conn_t *)conn)->ctx, user, pass,
954 passlen, oldpass, oldpasslen, flags);
955 }
956
sasl_checkapop(sasl_conn_t * conn,const char * challenge,unsigned challen,const char * response,unsigned resplen)957 int sasl_checkapop(sasl_conn_t *conn,
958 const char *challenge, unsigned challen,
959 const char *response, unsigned resplen)
960 {
961 if (!_cfmsasl_initted)
962 return SASL_NOMEM;
963 if (!saslcfmglob.sasl_checkapopPtr) return SASL_NOMEM;
964
965 return saslcfmglob.sasl_checkapopPtr(((cfm_sasl_conn_t *)conn)->ctx, challenge, challen,
966 response, resplen);
967 }
968
sasl_auxprop_request(sasl_conn_t * conn,const char ** propnames)969 int sasl_auxprop_request(sasl_conn_t *conn,
970 const char **propnames)
971 {
972 if (!_cfmsasl_initted)
973 return SASL_NOMEM;
974 if (!saslcfmglob.sasl_auxprop_requestPtr) return SASL_NOMEM;
975
976 return saslcfmglob.sasl_auxprop_requestPtr(((cfm_sasl_conn_t *)conn)->ctx, propnames);
977 }
978
sasl_auxprop_getctx(sasl_conn_t * conn)979 struct propctx *sasl_auxprop_getctx(sasl_conn_t *conn)
980 {
981 if (!_cfmsasl_initted)
982 return NULL;
983 if (!saslcfmglob.sasl_auxprop_getctxPtr) return NULL;
984
985 return saslcfmglob.sasl_auxprop_getctxPtr(((cfm_sasl_conn_t *)conn)->ctx);
986 }
987
sasl_erasebuffer(char * pass,unsigned len)988 void sasl_erasebuffer(char *pass, unsigned len)
989 {
990 if (!_cfmsasl_initted)
991 return;
992 if (!saslcfmglob.sasl_erasebufferPtr) return;
993
994 saslcfmglob.sasl_erasebufferPtr(pass, len);
995 }
996
prop_new(unsigned estimate)997 struct propctx *prop_new(unsigned estimate)
998 {
999 if (!_cfmsasl_initted)
1000 return NULL;
1001 if (!saslcfmglob.prop_newPtr) return NULL;
1002
1003 return saslcfmglob.prop_newPtr(estimate);
1004 }
1005
prop_dup(struct propctx * src_ctx,struct propctx ** dst_ctx)1006 int prop_dup(struct propctx *src_ctx, struct propctx **dst_ctx)
1007 {
1008 if (!_cfmsasl_initted)
1009 return SASL_NOMEM;
1010 if (!saslcfmglob.prop_dupPtr) return SASL_NOMEM;
1011
1012 return saslcfmglob.prop_dupPtr(src_ctx, dst_ctx);
1013 }
1014
prop_get(struct propctx * ctx)1015 const struct propval *prop_get(struct propctx *ctx)
1016 {
1017 if (!_cfmsasl_initted)
1018 return NULL;
1019 if (!saslcfmglob.prop_getPtr) return NULL;
1020
1021 return saslcfmglob.prop_getPtr(ctx);
1022 }
1023
prop_getnames(struct propctx * ctx,const char ** names,struct propval * vals)1024 int prop_getnames(struct propctx *ctx, const char **names,
1025 struct propval *vals)
1026 {
1027 if (!_cfmsasl_initted)
1028 return SASL_NOMEM;
1029 if (!saslcfmglob.prop_getnamesPtr) return SASL_NOMEM;
1030
1031 return saslcfmglob.prop_getnamesPtr(ctx, names, vals);
1032 }
1033
prop_clear(struct propctx * ctx,int requests)1034 void prop_clear(struct propctx *ctx, int requests)
1035 {
1036 if (!_cfmsasl_initted)
1037 return;
1038 if (!saslcfmglob.prop_clearPtr) return;
1039
1040 saslcfmglob.prop_clearPtr(ctx, requests);
1041 }
1042
prop_erase(struct propctx * ctx,const char * name)1043 void prop_erase(struct propctx *ctx, const char *name)
1044 {
1045 if (!_cfmsasl_initted)
1046 return;
1047 if (!saslcfmglob.prop_erasePtr) return;
1048
1049 saslcfmglob.prop_erasePtr(ctx, name);
1050 }
1051
prop_dispose(struct propctx ** ctx)1052 void prop_dispose(struct propctx **ctx)
1053 {
1054 if (!_cfmsasl_initted)
1055 return;
1056 if (!saslcfmglob.prop_disposePtr) return;
1057
1058 saslcfmglob.prop_disposePtr(ctx);
1059 }
1060
prop_format(struct propctx * ctx,const char * sep,int seplen,char * outbuf,unsigned outmax,unsigned * outlen)1061 int prop_format(struct propctx *ctx, const char *sep, int seplen,
1062 char *outbuf, unsigned outmax, unsigned *outlen)
1063 {
1064 if (!_cfmsasl_initted)
1065 return SASL_NOMEM;
1066 if (!saslcfmglob.prop_formatPtr) return SASL_NOMEM;
1067
1068 return saslcfmglob.prop_formatPtr(ctx, sep, seplen, outbuf, outmax, outlen);
1069 }
1070
prop_set(struct propctx * ctx,const char * name,const char * value,int vallen)1071 int prop_set(struct propctx *ctx, const char *name,
1072 const char *value, int vallen)
1073 {
1074 if (!_cfmsasl_initted)
1075 return SASL_NOMEM;
1076 if (!saslcfmglob.prop_setPtr) return SASL_NOMEM;
1077
1078 return saslcfmglob.prop_setPtr(ctx, name, value, vallen);
1079 }
1080
prop_setvals(struct propctx * ctx,const char * name,const char ** values)1081 int prop_setvals(struct propctx *ctx, const char *name,
1082 const char **values)
1083 {
1084 if (!_cfmsasl_initted)
1085 return SASL_NOMEM;
1086 if (!saslcfmglob.prop_setvalsPtr) return SASL_NOMEM;
1087
1088 return saslcfmglob.prop_setvalsPtr(ctx, name, values);
1089 }
1090
1091 /* internal functions used by sasl_seterror follow */
_sasl_add_string(char ** out,int * alloclen,int * outlen,const char * add)1092 int _sasl_add_string(char **out, int *alloclen, int *outlen, const char *add)
1093 {
1094 if (!_cfmsasl_initted)
1095 return SASL_NOMEM;
1096 if (!saslcfmglob._sasl_add_stringPtr) return SASL_NOMEM;
1097
1098 return saslcfmglob._sasl_add_stringPtr(out, alloclen, outlen, add);
1099 }
1100
_buf_alloc(char ** rwbuf,unsigned * curlen,unsigned newlen)1101 int _buf_alloc(char **rwbuf, unsigned *curlen, unsigned newlen)
1102 {
1103 if (!_cfmsasl_initted)
1104 return SASL_NOMEM;
1105 if (!saslcfmglob._buf_allocPtr) return SASL_NOMEM;
1106
1107 return saslcfmglob._buf_allocPtr(rwbuf, curlen, newlen);
1108 }
1109
_sasl_get_errorbuf(sasl_conn_t * conn,char *** bufhdl,unsigned ** lenhdl)1110 void _sasl_get_errorbuf(sasl_conn_t *conn, char ***bufhdl, unsigned **lenhdl)
1111 {
1112 if (!_cfmsasl_initted)
1113 return;
1114 if (!saslcfmglob._sasl_add_stringPtr) return;
1115
1116 saslcfmglob._sasl_get_errorbufPtr(((cfm_sasl_conn_t *)conn)->ctx, bufhdl, lenhdl);
1117 }
1118