2 by Rolf Braun, for CMU SASL on Mac OS X
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 $
10 * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved.
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
16 * 1. Redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer.
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
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
31 * Pittsburgh, PA 15213-3890
32 * (412) 268-4387, fax: (412) 268-7395
33 * tech-transfer@andrew.cmu.edu
35 * 4. Redistributions of any form whatsoever must retain the following
37 * "This product includes software developed by Computing Services
38 * at Carnegie Mellon University (http://www.cmu.edu/computing/)."
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.
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);
61 void *MachOFunctionPointerForCFMFunctionPointer( void *cfmfp );
62 sasl_callback_t *GetCFMCallbacks(const sasl_callback_t *callbacks);
63 void DisposeCFMCallbacks(sasl_callback_t *callbacks);
65 int _cfmsasl_haveCustomAlloc = 0;
66 int _cfmsasl_haveCustomMutex = 0;
67 int _cfmsasl_initted = 0;
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! */
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,
91 int (*SASLClientStartPtr)(sasl_conn_t *conn,
93 sasl_interact_t **prompt_need,
94 const char **clientout,
95 unsigned *clientoutlen,
97 int (*SASLClientStepPtr)(sasl_conn_t *conn,
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,
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,
134 void (*sasl_randPtr)(sasl_rand_t *rpool,
137 void (*sasl_randseedPtr)(sasl_rand_t *rpool,
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,
151 sasl_conn_t **pconn);
152 int (*sasl_listmechPtr)(sasl_conn_t *conn,
160 int (*SASLServerStartPtr)(sasl_conn_t *conn,
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,
176 int (*sasl_user_existsPtr)(sasl_conn_t *conn,
178 const char *user_realm,
180 int (*sasl_setpassPtr)(sasl_conn_t *conn,
184 const char *oldpass, unsigned oldpasslen,
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);
215 sasl_malloc_t *custMalloc;
216 sasl_calloc_t *custCalloc;
217 sasl_realloc_t *custRealloc;
218 sasl_free_t *custFree;
220 sasl_mutex_alloc_t *custMutexNew;
221 sasl_mutex_lock_t *custMutexLock;
222 sasl_mutex_unlock_t *custMutexUnlock;
223 sasl_mutex_free_t *custMutexDispose;
229 sasl_callback_t *cbk;
232 GlobalsRec saslcfmglob; // The globals
233 GlobalParamsRec saslcfmglobp;
235 // From Apple sample code... (CarbonLib SDK, CFM->MachO->CFM)
237 // This function allocates a block of CFM glue code which contains the instructions to call CFM routines
239 void *MachOFunctionPointerForCFMFunctionPointer( void *cfmfp )
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) );
253 sasl_callback_t *GetCFMCallbacks(const sasl_callback_t *callbacks)
256 const sasl_callback_t *cbk = callbacks;
257 sasl_callback_t *ncbk, *new_callbacks;
261 cbksize++; cbk = callbacks;
263 ncbk = new_callbacks = (sasl_callback_t *)NewPtr(cbksize * sizeof(sasl_callback_t));
264 if (!ncbk) return nil;
267 ncbk->context = cbk->context;
269 ncbk->proc = MachOFunctionPointerForCFMFunctionPointer(cbk->proc);
270 else ncbk->proc = nil;
273 return new_callbacks;
276 void DisposeCFMCallbacks(sasl_callback_t *callbacks)
278 sasl_callback_t *cbk = callbacks;
281 if (cbk->proc) DisposePtr((Ptr)cbk->proc);
284 DisposePtr((Ptr)callbacks);
287 int _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)
291 int (*SASLClientInitPtr)(const sasl_callback_t *callbacks);
292 int (*SASLServerInitPtr)(const sasl_callback_t *callbacks, const char *appname);
293 int result = SASL_NOMEM;
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
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
308 if ( saslcfmglob.bundleURL != NULL )
310 // Make a bundle instance using the URLRef.
311 saslcfmglob.myBundle = CFBundleCreate(
312 NULL /* kCFAllocatorDefault */, // workaround for Radar # 2452789
313 saslcfmglob.bundleURL );
315 if ( saslcfmglob.myBundle && CFBundleLoadExecutable( saslcfmglob.myBundle )) { // Try to load the executable from my bundle.
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") );
321 saslcfmglob.SASLClientStartPtr = (void*)CFBundleGetFunctionPointerForName(
322 saslcfmglob.myBundle, CFSTR("sasl_client_start") );
324 saslcfmglob.SASLClientStepPtr = (void*)CFBundleGetFunctionPointerForName(
325 saslcfmglob.myBundle, CFSTR("sasl_client_step") );
327 saslcfmglob.SASLErrStringPtr = (void*)CFBundleGetFunctionPointerForName(
328 saslcfmglob.myBundle, CFSTR("sasl_errstring") );
330 saslcfmglob.sasl_errdetailPtr = (void*)CFBundleGetFunctionPointerForName(
331 saslcfmglob.myBundle, CFSTR("sasl_errdetail") );
333 saslcfmglob.SASLGetPropPtr = (void*)CFBundleGetFunctionPointerForName(
334 saslcfmglob.myBundle, CFSTR("sasl_getprop") );
336 saslcfmglob.SASLSetPropPtr = (void*)CFBundleGetFunctionPointerForName(
337 saslcfmglob.myBundle, CFSTR("sasl_setprop") );
339 saslcfmglob.SASLIdlePtr = (void*)CFBundleGetFunctionPointerForName(
340 saslcfmglob.myBundle, CFSTR("sasl_idle") );
342 saslcfmglob.SASLEncodePtr = (void*)CFBundleGetFunctionPointerForName(
343 saslcfmglob.myBundle, CFSTR("sasl_encode") );
345 saslcfmglob.SASLEncodeVPtr = (void*)CFBundleGetFunctionPointerForName(
346 saslcfmglob.myBundle, CFSTR("sasl_encodev") );
348 saslcfmglob.SASLDecodePtr = (void*)CFBundleGetFunctionPointerForName(
349 saslcfmglob.myBundle, CFSTR("sasl_decode") );
351 saslcfmglob.SASLDisposePtr = (void*)CFBundleGetFunctionPointerForName(
352 saslcfmglob.myBundle, CFSTR("sasl_dispose") );
354 saslcfmglob.SASLDonePtr = (void*)CFBundleGetFunctionPointerForName(
355 saslcfmglob.myBundle, CFSTR("sasl_done") );
357 saslcfmglob.SASLSetAllocPtr = (void*)CFBundleGetFunctionPointerForName(
358 saslcfmglob.myBundle, CFSTR("sasl_set_alloc") );
360 saslcfmglob.sasl_encode64Ptr = (void*)CFBundleGetFunctionPointerForName(
361 saslcfmglob.myBundle, CFSTR("sasl_encode64") );
363 saslcfmglob.sasl_decode64Ptr = (void*)CFBundleGetFunctionPointerForName(
364 saslcfmglob.myBundle, CFSTR("sasl_decode64") );
366 saslcfmglob.sasl_mkchalPtr = (void*)CFBundleGetFunctionPointerForName(
367 saslcfmglob.myBundle, CFSTR("sasl_mkchal") );
369 saslcfmglob.sasl_utf8verifyPtr = (void*)CFBundleGetFunctionPointerForName(
370 saslcfmglob.myBundle, CFSTR("sasl_utf8verify") );
372 saslcfmglob.sasl_churnPtr = (void*)CFBundleGetFunctionPointerForName(
373 saslcfmglob.myBundle, CFSTR("sasl_churn") );
375 saslcfmglob.sasl_randPtr = (void*)CFBundleGetFunctionPointerForName(
376 saslcfmglob.myBundle, CFSTR("sasl_rand") );
378 saslcfmglob.sasl_randseedPtr = (void*)CFBundleGetFunctionPointerForName(
379 saslcfmglob.myBundle, CFSTR("sasl_randseed") );
381 saslcfmglob.sasl_randcreatePtr = (void*)CFBundleGetFunctionPointerForName(
382 saslcfmglob.myBundle, CFSTR("sasl_randcreate") );
384 saslcfmglob.sasl_randfreePtr = (void*)CFBundleGetFunctionPointerForName(
385 saslcfmglob.myBundle, CFSTR("sasl_randfree") );
387 saslcfmglob.SASLSetMutexPtr = (void*)CFBundleGetFunctionPointerForName(
388 saslcfmglob.myBundle, CFSTR("sasl_set_mutex") );
390 saslcfmglob.SASLServerNewPtr = (void*)CFBundleGetFunctionPointerForName(
391 saslcfmglob.myBundle, CFSTR("sasl_server_new") );
393 saslcfmglob.SASLServerStartPtr = (void*)CFBundleGetFunctionPointerForName(
394 saslcfmglob.myBundle, CFSTR("sasl_server_start") );
396 saslcfmglob.SASLServerStepPtr = (void*)CFBundleGetFunctionPointerForName(
397 saslcfmglob.myBundle, CFSTR("sasl_server_step") );
399 saslcfmglob.sasl_listmechPtr = (void*)CFBundleGetFunctionPointerForName(
400 saslcfmglob.myBundle, CFSTR("sasl_listmech") );
402 saslcfmglob.sasl_checkpassPtr = (void*)CFBundleGetFunctionPointerForName(
403 saslcfmglob.myBundle, CFSTR("sasl_checkpass") );
405 saslcfmglob.sasl_setpassPtr = (void*)CFBundleGetFunctionPointerForName(
406 saslcfmglob.myBundle, CFSTR("sasl_setpass") );
408 saslcfmglob.sasl_user_existsPtr = (void*)CFBundleGetFunctionPointerForName(
409 saslcfmglob.myBundle, CFSTR("sasl_user_exists") );
411 saslcfmglob.sasl_checkapopPtr = (void*)CFBundleGetFunctionPointerForName(
412 saslcfmglob.myBundle, CFSTR("sasl_checkapop") );
414 saslcfmglob.sasl_auxprop_requestPtr = (void*)CFBundleGetFunctionPointerForName(
415 saslcfmglob.myBundle, CFSTR("sasl_auxprop_request") );
417 saslcfmglob.sasl_auxprop_getctxPtr = (void*)CFBundleGetFunctionPointerForName(
418 saslcfmglob.myBundle, CFSTR("sasl_auxprop_getctx") );
420 saslcfmglob.sasl_erasebufferPtr = (void*)CFBundleGetFunctionPointerForName(
421 saslcfmglob.myBundle, CFSTR("sasl_erasebuffer") );
423 saslcfmglob.prop_newPtr = (void*)CFBundleGetFunctionPointerForName(
424 saslcfmglob.myBundle, CFSTR("prop_new") );
426 saslcfmglob.prop_dupPtr = (void*)CFBundleGetFunctionPointerForName(
427 saslcfmglob.myBundle, CFSTR("prop_dup") );
429 saslcfmglob.prop_getPtr = (void*)CFBundleGetFunctionPointerForName(
430 saslcfmglob.myBundle, CFSTR("prop_get") );
432 saslcfmglob.prop_getnamesPtr = (void*)CFBundleGetFunctionPointerForName(
433 saslcfmglob.myBundle, CFSTR("prop_getnames") );
435 saslcfmglob.prop_clearPtr = (void*)CFBundleGetFunctionPointerForName(
436 saslcfmglob.myBundle, CFSTR("prop_clear") );
438 saslcfmglob.prop_erasePtr = (void*)CFBundleGetFunctionPointerForName(
439 saslcfmglob.myBundle, CFSTR("prop_erase") );
441 saslcfmglob.prop_disposePtr = (void*)CFBundleGetFunctionPointerForName(
442 saslcfmglob.myBundle, CFSTR("prop_dispose") );
444 saslcfmglob.prop_formatPtr = (void*)CFBundleGetFunctionPointerForName(
445 saslcfmglob.myBundle, CFSTR("prop_format") );
447 saslcfmglob.prop_setPtr = (void*)CFBundleGetFunctionPointerForName(
448 saslcfmglob.myBundle, CFSTR("prop_set") );
450 saslcfmglob.prop_setvalsPtr = (void*)CFBundleGetFunctionPointerForName(
451 saslcfmglob.myBundle, CFSTR("prop_setvals") );
453 /* These are internal functions used by our sasl_seterror */
454 saslcfmglob._sasl_add_stringPtr = (void*)CFBundleGetFunctionPointerForName(
455 saslcfmglob.myBundle, CFSTR("_sasl_add_string") );
457 saslcfmglob._buf_allocPtr = (void*)CFBundleGetFunctionPointerForName(
458 saslcfmglob.myBundle, CFSTR("_buf_alloc") );
460 saslcfmglob._sasl_get_errorbufPtr = (void*)CFBundleGetFunctionPointerForName(
461 saslcfmglob.myBundle, CFSTR("_sasl_get_errorbuf") );
463 if (!_cfmsasl_haveCustomAlloc) {
464 saslcfmglobp.custMalloc = MachOFunctionPointerForCFMFunctionPointer(malloc);
465 saslcfmglobp.custCalloc = MachOFunctionPointerForCFMFunctionPointer(calloc);
466 saslcfmglobp.custRealloc = MachOFunctionPointerForCFMFunctionPointer(realloc);
467 saslcfmglobp.custFree = MachOFunctionPointerForCFMFunctionPointer(free);
469 _cfmsasl_haveCustomAlloc = 1;
472 saslcfmglob.SASLSetAllocPtr(saslcfmglobp.custMalloc, saslcfmglobp.custCalloc,
473 saslcfmglobp.custRealloc, saslcfmglobp.custFree);
475 if (_cfmsasl_haveCustomMutex)
476 saslcfmglob.SASLSetMutexPtr(saslcfmglobp.custMutexNew, saslcfmglobp.custMutexLock,
477 saslcfmglobp.custMutexUnlock, saslcfmglobp.custMutexDispose);
479 } else if (saslcfmglob.myBundle) {
480 CFRelease(saslcfmglob.myBundle);
481 saslcfmglob.myBundle = nil;
484 if (saslcfmglob.bundleURL && !saslcfmglob.myBundle) {
485 CFRelease(saslcfmglob.bundleURL);
486 saslcfmglob.bundleURL = nil;
489 if (saslcfmglob.myBundle)
490 _cfmsasl_initted = 1;
493 if (_cfmsasl_initted) {
495 SASLServerInitPtr = (void*)CFBundleGetFunctionPointerForName(
496 saslcfmglob.myBundle, CFSTR("sasl_server_init") );
497 if (SASLServerInitPtr != nil) {
498 sasl_callback_t *new_callbacks = NULL;
500 new_callbacks = GetCFMCallbacks(callbacks);
501 result = SASLServerInitPtr(new_callbacks, appname);
502 saslcfmglob.serverCallbacks = new_callbacks;
505 SASLClientInitPtr = (void*)CFBundleGetFunctionPointerForName(
506 saslcfmglob.myBundle, CFSTR("sasl_client_init") );
507 if (SASLClientInitPtr != nil) {
508 sasl_callback_t *new_callbacks = NULL;
510 new_callbacks = GetCFMCallbacks(callbacks);
511 result = SASLClientInitPtr(new_callbacks);
512 saslcfmglob.clientCallbacks = new_callbacks;
519 int sasl_server_init(const sasl_callback_t *callbacks,
522 return _cfmsasl_common_init(callbacks, true, appname);
525 int sasl_client_init(const sasl_callback_t *callbacks)
527 return _cfmsasl_common_init(callbacks, false, nil);
532 if (!_cfmsasl_initted)
534 if (!saslcfmglob.SASLDonePtr) return;
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;
545 _cfmsasl_initted = 0;
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,
556 sasl_callback_t *new_ps = NULL;
558 cfm_sasl_conn_t *myconn;
560 if (!_cfmsasl_initted)
562 if (!saslcfmglob.SASLClientNewPtr) return SASL_NOMEM;
565 new_ps = GetCFMCallbacks(prompt_supp);
567 // this is commented out because sasl.h incorrectly described the api
569 // DisposeCFMCallbacks(((cfm_sasl_conn_t *)*pconn)->cbk);
571 myconn = (cfm_sasl_conn_t *) NewPtr(sizeof(cfm_sasl_conn_t));
572 if (myconn == NULL) {
579 result = saslcfmglob.SASLClientNewPtr(service, serverFQDN, iplocalport,
580 ipremoteport, new_ps, flags,
582 myconn->cbk = new_ps;
584 *pconn = (sasl_conn_t *)myconn;
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,
598 sasl_callback_t *new_ps = NULL;
601 if (!_cfmsasl_initted)
603 if (!saslcfmglob.SASLServerNewPtr) return SASL_NOMEM;
606 new_ps = GetCFMCallbacks(callbacks);
607 *pconn = (sasl_conn_t *)NewPtr(sizeof(cfm_sasl_conn_t));
608 ((cfm_sasl_conn_t *)*pconn)->ctx = nil;
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;
618 void sasl_dispose(sasl_conn_t **pconn)
620 if (!_cfmsasl_initted)
622 if (!saslcfmglob.SASLDisposePtr) return;
627 saslcfmglob.SASLDisposePtr(&((cfm_sasl_conn_t *)*pconn)->ctx);
628 DisposeCFMCallbacks(((cfm_sasl_conn_t *)*pconn)->cbk);
629 DisposePtr((Ptr)*pconn);
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,
640 if (!_cfmsasl_initted)
642 if (!saslcfmglob.SASLClientStartPtr) return SASL_NOMEM;
644 return saslcfmglob.SASLClientStartPtr(((cfm_sasl_conn_t *)conn)->ctx, mechlist,
645 prompt_need, clientout, clientoutlen, mech);
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)
655 if (!_cfmsasl_initted)
657 if (!saslcfmglob.SASLClientStepPtr) return SASL_NOMEM;
659 return saslcfmglob.SASLClientStepPtr(((cfm_sasl_conn_t *)conn)->ctx, serverin,
660 serverinlen, prompt_need, clientout, clientoutlen);
663 const char *sasl_errstring(int saslerr,
664 const char *langlist,
665 const char **outlang)
667 if (!_cfmsasl_initted)
669 if (!saslcfmglob.SASLErrStringPtr) return NULL;
671 return saslcfmglob.SASLErrStringPtr(saslerr, langlist, outlang);
674 const char *sasl_errdetail(sasl_conn_t *conn)
676 if (!_cfmsasl_initted)
678 if (!saslcfmglob.sasl_errdetailPtr) return NULL;
680 return saslcfmglob.sasl_errdetailPtr(((cfm_sasl_conn_t *)conn)->ctx);
683 int sasl_getprop(sasl_conn_t *conn, int propnum, const void **pvalue)
685 if (!_cfmsasl_initted)
687 if (!saslcfmglob.SASLGetPropPtr) return SASL_NOMEM;
689 return saslcfmglob.SASLGetPropPtr(((cfm_sasl_conn_t *)conn)->ctx, propnum, pvalue);
692 int sasl_setprop(sasl_conn_t *conn,
696 if (!_cfmsasl_initted)
698 if (!saslcfmglob.SASLSetPropPtr) return SASL_NOMEM;
700 return saslcfmglob.SASLSetPropPtr(((cfm_sasl_conn_t *)conn)->ctx, propnum, value);
703 int sasl_idle(sasl_conn_t *conn)
705 if (!_cfmsasl_initted)
707 if (!saslcfmglob.SASLIdlePtr) return SASL_NOMEM;
709 return saslcfmglob.SASLIdlePtr(((cfm_sasl_conn_t *)conn)->ctx);
712 int sasl_encode(sasl_conn_t *conn,
713 const char *input, unsigned inputlen,
714 const char **output, unsigned *outputlen)
716 if (!_cfmsasl_initted)
718 if (!saslcfmglob.SASLEncodePtr) return SASL_NOMEM;
720 return saslcfmglob.SASLEncodePtr(((cfm_sasl_conn_t *)conn)->ctx, input, inputlen,
724 int sasl_encodev(sasl_conn_t *conn,
725 const struct iovec *invec, unsigned numiov,
726 const char **output, unsigned *outputlen)
728 if (!_cfmsasl_initted)
730 if (!saslcfmglob.SASLEncodeVPtr) return SASL_NOMEM;
732 return saslcfmglob.SASLEncodeVPtr(((cfm_sasl_conn_t *)conn)->ctx, invec, numiov,
736 int sasl_decode(sasl_conn_t *conn,
737 const char *input, unsigned inputlen,
738 const char **output, unsigned *outputlen)
740 if (!_cfmsasl_initted)
742 if (!saslcfmglob.SASLDecodePtr) return SASL_NOMEM;
744 return saslcfmglob.SASLDecodePtr(((cfm_sasl_conn_t *)conn)->ctx, input, inputlen,
748 int sasl_decode64(const char *in, unsigned inlen,
749 char *out, unsigned outmax, unsigned *outlen)
751 if (!_cfmsasl_initted)
753 if (!saslcfmglob.sasl_decode64Ptr) return SASL_NOMEM;
755 return saslcfmglob.sasl_decode64Ptr(in, inlen, out, outmax, outlen);
758 int sasl_encode64(const char *in, unsigned inlen,
759 char *out, unsigned outmax, unsigned *outlen)
761 if (!_cfmsasl_initted)
763 if (!saslcfmglob.sasl_encode64Ptr) return SASL_NOMEM;
765 return saslcfmglob.sasl_encode64Ptr(in, inlen, out, outmax, outlen);
768 void sasl_set_alloc(sasl_malloc_t *ma, sasl_calloc_t *ca, sasl_realloc_t *rea, sasl_free_t *fr)
770 if (_cfmsasl_haveCustomAlloc) {
771 DisposePtr((Ptr)saslcfmglobp.custMalloc);
772 DisposePtr((Ptr)saslcfmglobp.custCalloc);
773 DisposePtr((Ptr)saslcfmglobp.custRealloc);
774 DisposePtr((Ptr)saslcfmglobp.custFree);
776 saslcfmglobp.custMalloc = MachOFunctionPointerForCFMFunctionPointer(ma);
777 saslcfmglobp.custCalloc = MachOFunctionPointerForCFMFunctionPointer(ca);
778 saslcfmglobp.custRealloc = MachOFunctionPointerForCFMFunctionPointer(rea);
779 saslcfmglobp.custFree = MachOFunctionPointerForCFMFunctionPointer(fr);
780 _cfmsasl_haveCustomAlloc = 1;
783 int sasl_mkchal(sasl_conn_t *conn, char *buf,
784 unsigned maxlen, unsigned hostflag)
786 if (!_cfmsasl_initted)
788 if (!saslcfmglob.sasl_mkchalPtr) return SASL_NOMEM;
790 return saslcfmglob.sasl_mkchalPtr(((cfm_sasl_conn_t *)conn)->ctx, buf, maxlen, hostflag);
793 int sasl_utf8verify(const char *str, unsigned len)
795 if (!_cfmsasl_initted)
797 if (!saslcfmglob.sasl_utf8verifyPtr) return SASL_NOMEM;
799 return saslcfmglob.sasl_utf8verifyPtr(str, len);
802 void sasl_churn(sasl_rand_t *rpool,
806 if (!_cfmsasl_initted)
808 if (!saslcfmglob.sasl_churnPtr) return;
810 saslcfmglob.sasl_churnPtr(rpool, data, len);
813 void sasl_rand(sasl_rand_t *rpool,
817 if (!_cfmsasl_initted)
819 if (!saslcfmglob.sasl_randPtr) return;
821 saslcfmglob.sasl_randPtr(rpool, buf, len);
824 void sasl_randseed(sasl_rand_t *rpool,
828 if (!_cfmsasl_initted)
830 if (!saslcfmglob.sasl_randseedPtr) return;
832 saslcfmglob.sasl_randseedPtr(rpool, seed, len);
835 void sasl_randfree(sasl_rand_t **rpool)
837 if (!_cfmsasl_initted)
839 if (!saslcfmglob.sasl_randfreePtr) return;
841 saslcfmglob.sasl_randfreePtr(rpool);
844 int sasl_randcreate(sasl_rand_t **rpool)
846 if (!_cfmsasl_initted)
848 if (!saslcfmglob.sasl_randcreatePtr) return SASL_NOMEM;
850 return saslcfmglob.sasl_randcreatePtr(rpool);
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)
856 if (_cfmsasl_haveCustomMutex) {
857 DisposePtr((Ptr)saslcfmglobp.custMutexNew);
858 DisposePtr((Ptr)saslcfmglobp.custMutexLock);
859 DisposePtr((Ptr)saslcfmglobp.custMutexUnlock);
860 DisposePtr((Ptr)saslcfmglobp.custMutexDispose);
862 saslcfmglobp.custMutexNew = MachOFunctionPointerForCFMFunctionPointer(mn);
863 saslcfmglobp.custMutexLock = MachOFunctionPointerForCFMFunctionPointer(ml);
864 saslcfmglobp.custMutexUnlock = MachOFunctionPointerForCFMFunctionPointer(mu);
865 saslcfmglobp.custMutexDispose = MachOFunctionPointerForCFMFunctionPointer(md);
866 _cfmsasl_haveCustomMutex = 1;
869 int sasl_listmech(sasl_conn_t *conn,
878 if (!_cfmsasl_initted)
880 if (!saslcfmglob.sasl_listmechPtr) return SASL_NOMEM;
882 return saslcfmglob.sasl_listmechPtr(((cfm_sasl_conn_t *)conn)->ctx, user, prefix, sep,
883 suffix, result, plen, pcount);
886 int sasl_server_start(sasl_conn_t *conn,
888 const char *clientin,
889 unsigned clientinlen,
890 const char **serverout,
891 unsigned *serveroutlen)
893 if (!_cfmsasl_initted)
895 if (!saslcfmglob.SASLServerStartPtr) return SASL_NOMEM;
897 return saslcfmglob.SASLServerStartPtr(((cfm_sasl_conn_t *)conn)->ctx, mech, clientin,
898 clientinlen, serverout, serveroutlen);
901 int sasl_server_step(sasl_conn_t *conn,
902 const char *clientin,
903 unsigned clientinlen,
904 const char **serverout,
905 unsigned *serveroutlen)
907 if (!_cfmsasl_initted)
909 if (!saslcfmglob.SASLServerStepPtr) return SASL_NOMEM;
911 return saslcfmglob.SASLServerStepPtr(((cfm_sasl_conn_t *)conn)->ctx, clientin, clientinlen,
912 serverout, serveroutlen);
915 int sasl_checkpass(sasl_conn_t *conn,
921 if (!_cfmsasl_initted)
923 if (!saslcfmglob.sasl_checkpassPtr) return SASL_NOMEM;
925 return saslcfmglob.sasl_checkpassPtr(((cfm_sasl_conn_t *)conn)->ctx, user, userlen, pass,
929 int sasl_user_exists(sasl_conn_t *conn,
931 const char *user_realm,
934 if (!_cfmsasl_initted)
936 if (!saslcfmglob.sasl_user_existsPtr) return SASL_NOMEM;
938 return saslcfmglob.sasl_user_existsPtr(((cfm_sasl_conn_t *)conn)->ctx,
939 service, user_realm, user);
942 int sasl_setpass(sasl_conn_t *conn,
946 const char *oldpass, unsigned oldpasslen,
949 if (!_cfmsasl_initted)
951 if (!saslcfmglob.sasl_setpassPtr) return SASL_NOMEM;
953 return saslcfmglob.sasl_setpassPtr(((cfm_sasl_conn_t *)conn)->ctx, user, pass,
954 passlen, oldpass, oldpasslen, flags);
957 int sasl_checkapop(sasl_conn_t *conn,
958 const char *challenge, unsigned challen,
959 const char *response, unsigned resplen)
961 if (!_cfmsasl_initted)
963 if (!saslcfmglob.sasl_checkapopPtr) return SASL_NOMEM;
965 return saslcfmglob.sasl_checkapopPtr(((cfm_sasl_conn_t *)conn)->ctx, challenge, challen,
969 int sasl_auxprop_request(sasl_conn_t *conn,
970 const char **propnames)
972 if (!_cfmsasl_initted)
974 if (!saslcfmglob.sasl_auxprop_requestPtr) return SASL_NOMEM;
976 return saslcfmglob.sasl_auxprop_requestPtr(((cfm_sasl_conn_t *)conn)->ctx, propnames);
979 struct propctx *sasl_auxprop_getctx(sasl_conn_t *conn)
981 if (!_cfmsasl_initted)
983 if (!saslcfmglob.sasl_auxprop_getctxPtr) return NULL;
985 return saslcfmglob.sasl_auxprop_getctxPtr(((cfm_sasl_conn_t *)conn)->ctx);
988 void sasl_erasebuffer(char *pass, unsigned len)
990 if (!_cfmsasl_initted)
992 if (!saslcfmglob.sasl_erasebufferPtr) return;
994 saslcfmglob.sasl_erasebufferPtr(pass, len);
997 struct propctx *prop_new(unsigned estimate)
999 if (!_cfmsasl_initted)
1001 if (!saslcfmglob.prop_newPtr) return NULL;
1003 return saslcfmglob.prop_newPtr(estimate);
1006 int prop_dup(struct propctx *src_ctx, struct propctx **dst_ctx)
1008 if (!_cfmsasl_initted)
1010 if (!saslcfmglob.prop_dupPtr) return SASL_NOMEM;
1012 return saslcfmglob.prop_dupPtr(src_ctx, dst_ctx);
1015 const struct propval *prop_get(struct propctx *ctx)
1017 if (!_cfmsasl_initted)
1019 if (!saslcfmglob.prop_getPtr) return NULL;
1021 return saslcfmglob.prop_getPtr(ctx);
1024 int prop_getnames(struct propctx *ctx, const char **names,
1025 struct propval *vals)
1027 if (!_cfmsasl_initted)
1029 if (!saslcfmglob.prop_getnamesPtr) return SASL_NOMEM;
1031 return saslcfmglob.prop_getnamesPtr(ctx, names, vals);
1034 void prop_clear(struct propctx *ctx, int requests)
1036 if (!_cfmsasl_initted)
1038 if (!saslcfmglob.prop_clearPtr) return;
1040 saslcfmglob.prop_clearPtr(ctx, requests);
1043 void prop_erase(struct propctx *ctx, const char *name)
1045 if (!_cfmsasl_initted)
1047 if (!saslcfmglob.prop_erasePtr) return;
1049 saslcfmglob.prop_erasePtr(ctx, name);
1052 void prop_dispose(struct propctx **ctx)
1054 if (!_cfmsasl_initted)
1056 if (!saslcfmglob.prop_disposePtr) return;
1058 saslcfmglob.prop_disposePtr(ctx);
1061 int prop_format(struct propctx *ctx, const char *sep, int seplen,
1062 char *outbuf, unsigned outmax, unsigned *outlen)
1064 if (!_cfmsasl_initted)
1066 if (!saslcfmglob.prop_formatPtr) return SASL_NOMEM;
1068 return saslcfmglob.prop_formatPtr(ctx, sep, seplen, outbuf, outmax, outlen);
1071 int prop_set(struct propctx *ctx, const char *name,
1072 const char *value, int vallen)
1074 if (!_cfmsasl_initted)
1076 if (!saslcfmglob.prop_setPtr) return SASL_NOMEM;
1078 return saslcfmglob.prop_setPtr(ctx, name, value, vallen);
1081 int prop_setvals(struct propctx *ctx, const char *name,
1082 const char **values)
1084 if (!_cfmsasl_initted)
1086 if (!saslcfmglob.prop_setvalsPtr) return SASL_NOMEM;
1088 return saslcfmglob.prop_setvalsPtr(ctx, name, values);
1091 /* internal functions used by sasl_seterror follow */
1092 int _sasl_add_string(char **out, int *alloclen, int *outlen, const char *add)
1094 if (!_cfmsasl_initted)
1096 if (!saslcfmglob._sasl_add_stringPtr) return SASL_NOMEM;
1098 return saslcfmglob._sasl_add_stringPtr(out, alloclen, outlen, add);
1101 int _buf_alloc(char **rwbuf, unsigned *curlen, unsigned newlen)
1103 if (!_cfmsasl_initted)
1105 if (!saslcfmglob._buf_allocPtr) return SASL_NOMEM;
1107 return saslcfmglob._buf_allocPtr(rwbuf, curlen, newlen);
1110 void _sasl_get_errorbuf(sasl_conn_t *conn, char ***bufhdl, unsigned **lenhdl)
1112 if (!_cfmsasl_initted)
1114 if (!saslcfmglob._sasl_add_stringPtr) return;
1116 saslcfmglob._sasl_get_errorbufPtr(((cfm_sasl_conn_t *)conn)->ctx, bufhdl, lenhdl);