import cyrus-sasl-2.1.23
[cyrus-sasl.git] / mac / osx_cfm_glue / cfmglue.c
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 //
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
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
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
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
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
525 int sasl_client_init(const sasl_callback_t *callbacks)
526 {
527         return _cfmsasl_common_init(callbacks, false, nil);
528 }
529
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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 */
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
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
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 }