#include <Carbon.h>
#include <string.h>
#include <stdlib.h>
#include "sasl.h"
#include "saslutil.h"
#include "prop.h"
int _sasl_add_string(char **out, int *alloclen, int *outlen, const char *add);
int _buf_alloc(char **rwbuf, unsigned *curlen, unsigned newlen);
void _sasl_get_errorbuf(sasl_conn_t *conn, char ***bufhdl, unsigned **lenhdl);
void *MachOFunctionPointerForCFMFunctionPointer( void *cfmfp );
sasl_callback_t *GetCFMCallbacks(const sasl_callback_t *callbacks);
void DisposeCFMCallbacks(sasl_callback_t *callbacks);
int _cfmsasl_haveCustomAlloc = 0;
int _cfmsasl_haveCustomMutex = 0;
int _cfmsasl_initted = 0;
struct iovec {
char *iov_base;
long iov_len;
};
typedef struct
{
CFURLRef bundleURL;
CFBundleRef myBundle;
sasl_callback_t *clientCallbacks;
sasl_callback_t *serverCallbacks;
int (*SASLClientNewPtr)(const char *service,
const char *serverFQDN,
const char *iplocalport,
const char *ipremoteport,
const sasl_callback_t *prompt_supp,
unsigned flags,
sasl_conn_t **pconn);
int (*SASLClientStartPtr)(sasl_conn_t *conn,
const char *mechlist,
sasl_interact_t **prompt_need,
const char **clientout,
unsigned *clientoutlen,
const char **mech);
int (*SASLClientStepPtr)(sasl_conn_t *conn,
const char *serverin,
unsigned serverinlen,
sasl_interact_t **prompt_need,
const char **clientout,
unsigned *clientoutlen);
const char * (*SASLErrStringPtr)(int saslerr,
const char *langlist,
const char **outlang);
const char *(*sasl_errdetailPtr)(sasl_conn_t *conn);
int (*SASLGetPropPtr)(sasl_conn_t *conn, int propnum, const void **pvalue);
int (*SASLSetPropPtr)(sasl_conn_t *conn,
int propnum,
const void *value);
int (*SASLIdlePtr)(sasl_conn_t *conn);
int (*SASLEncodePtr)(sasl_conn_t *conn,
const char *input, unsigned inputlen,
const char **output, unsigned *outputlen);
int (*SASLDecodePtr)(sasl_conn_t *conn,
const char *input, unsigned inputlen,
const char **output, unsigned *outputlen);
int (*SASLEncodeVPtr)(sasl_conn_t *conn,
const struct iovec *invec, unsigned numiov,
const char **output, unsigned *outputlen);
int (*SASLDisposePtr)(sasl_conn_t **pconn);
int (*SASLDonePtr)();
void (*SASLSetAllocPtr)(sasl_malloc_t *, sasl_calloc_t *, sasl_realloc_t *, sasl_free_t *);
int (*sasl_decode64Ptr)(const char *in, unsigned inlen,
char *out, unsigned outmax, unsigned *outlen);
int (*sasl_encode64Ptr)(const char *in, unsigned inlen,
char *out, unsigned outmax, unsigned *outlen);
int (*sasl_mkchalPtr)(sasl_conn_t *conn, char *buf,
unsigned maxlen, unsigned hostflag);
int (*sasl_utf8verifyPtr)(const char *str, unsigned len);
void (*sasl_churnPtr)(sasl_rand_t *rpool,
const char *data,
unsigned len);
void (*sasl_randPtr)(sasl_rand_t *rpool,
char *buf,
unsigned len);
void (*sasl_randseedPtr)(sasl_rand_t *rpool,
const char *seed,
unsigned len);
void (*sasl_randfreePtr)(sasl_rand_t **rpool);
int (*sasl_randcreatePtr)(sasl_rand_t **rpool);
void (*SASLSetMutexPtr)(sasl_mutex_alloc_t *mn, sasl_mutex_lock_t *ml,
sasl_mutex_unlock_t *mu, sasl_mutex_free_t *md);
int (*SASLServerNewPtr)(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);
int (*sasl_listmechPtr)(sasl_conn_t *conn,
const char *user,
const char *prefix,
const char *sep,
const char *suffix,
const char **result,
unsigned *plen,
int *pcount);
int (*SASLServerStartPtr)(sasl_conn_t *conn,
const char *mech,
const char *clientin,
unsigned clientinlen,
const char **serverout,
unsigned *serveroutlen);
int (*SASLServerStepPtr)(sasl_conn_t *conn,
const char *clientin,
unsigned clientinlen,
const char **serverout,
unsigned *serveroutlen);
int (*sasl_checkpassPtr)(sasl_conn_t *conn,
const char *user,
unsigned userlen,
const char *pass,
unsigned passlen);
int (*sasl_user_existsPtr)(sasl_conn_t *conn,
const char *service,
const char *user_realm,
const char *user);
int (*sasl_setpassPtr)(sasl_conn_t *conn,
const char *user,
const char *pass,
unsigned passlen,
const char *oldpass, unsigned oldpasslen,
unsigned flags);
int (*sasl_checkapopPtr)(sasl_conn_t *conn,
const char *challenge, unsigned challen,
const char *response, unsigned resplen);
int (*sasl_auxprop_requestPtr)(sasl_conn_t *conn,
const char **propnames);
struct propctx *(*sasl_auxprop_getctxPtr)(sasl_conn_t *conn);
void (*sasl_erasebufferPtr)(char *pass, unsigned len);
struct propctx *(*prop_newPtr)(unsigned estimate);
int (*prop_dupPtr)(struct propctx *src_ctx, struct propctx **dst_ctx);
const struct propval *(*prop_getPtr)(struct propctx *ctx);
int (*prop_getnamesPtr)(struct propctx *ctx, const char **names,
struct propval *vals);
void (*prop_clearPtr)(struct propctx *ctx, int requests);
void (*prop_erasePtr)(struct propctx *ctx, const char *name);
void (*prop_disposePtr)(struct propctx **ctx);
int (*prop_formatPtr)(struct propctx *ctx, const char *sep, int seplen,
char *outbuf, unsigned outmax, unsigned *outlen);
int (*prop_setPtr)(struct propctx *ctx, const char *name,
const char *value, int vallen);
int (*prop_setvalsPtr)(struct propctx *ctx, const char *name,
const char **values);
int (*_sasl_add_stringPtr)(char **out, int *alloclen, int *outlen, const char *add);
int (*_buf_allocPtr)(char **rwbuf, unsigned *curlen, unsigned newlen);
void (*_sasl_get_errorbufPtr)(sasl_conn_t *conn, char ***bufhdl, unsigned **lenhdl);
} GlobalsRec;
typedef struct
{
sasl_malloc_t *custMalloc;
sasl_calloc_t *custCalloc;
sasl_realloc_t *custRealloc;
sasl_free_t *custFree;
sasl_mutex_alloc_t *custMutexNew;
sasl_mutex_lock_t *custMutexLock;
sasl_mutex_unlock_t *custMutexUnlock;
sasl_mutex_free_t *custMutexDispose;
} GlobalParamsRec;
typedef struct
{
sasl_conn_t *ctx;
sasl_callback_t *cbk;
} cfm_sasl_conn_t;
GlobalsRec saslcfmglob; GlobalParamsRec saslcfmglobp;
void *MachOFunctionPointerForCFMFunctionPointer( void *cfmfp )
{
UInt32 template[6] = {0x3D800000, 0x618C0000, 0x800C0000, 0x804C0004, 0x7C0903A6, 0x4E800420};
UInt32 *mfp = (UInt32*) NewPtr( sizeof(template) ); mfp[0] = template[0] | ((UInt32)cfmfp >> 16);
mfp[1] = template[1] | ((UInt32)cfmfp & 0xFFFF);
mfp[2] = template[2];
mfp[3] = template[3];
mfp[4] = template[4];
mfp[5] = template[5];
MakeDataExecutable( mfp, sizeof(template) );
return( mfp );
}
sasl_callback_t *GetCFMCallbacks(const sasl_callback_t *callbacks)
{
int cbksize = 0;
const sasl_callback_t *cbk = callbacks;
sasl_callback_t *ncbk, *new_callbacks;
while (cbk->id) {
cbksize++; cbk++;
}
cbksize++; cbk = callbacks;
ncbk = new_callbacks = (sasl_callback_t *)NewPtr(cbksize * sizeof(sasl_callback_t));
if (!ncbk) return nil;
while (cbksize--) {
ncbk->id = cbk->id;
ncbk->context = cbk->context;
if (cbk->proc)
ncbk->proc = MachOFunctionPointerForCFMFunctionPointer(cbk->proc);
else ncbk->proc = nil;
ncbk++; cbk++;
}
return new_callbacks;
}
void DisposeCFMCallbacks(sasl_callback_t *callbacks)
{
sasl_callback_t *cbk = callbacks;
if (!cbk) return;
while (cbk->id) {
if (cbk->proc) DisposePtr((Ptr)cbk->proc);
cbk++;
}
DisposePtr((Ptr)callbacks);
}
int _cfmsasl_common_init(const sasl_callback_t *callbacks, int isServer, const char *appname);
int _cfmsasl_common_init(const sasl_callback_t *callbacks, int isServer, const char *appname)
{
int (*SASLClientInitPtr)(const sasl_callback_t *callbacks);
int (*SASLServerInitPtr)(const sasl_callback_t *callbacks, const char *appname);
int result = SASL_NOMEM;
if (!_cfmsasl_initted) {
memset( &saslcfmglob, 0, sizeof(GlobalsRec) );
saslcfmglob.bundleURL = CFURLCreateWithFileSystemPath(
nil, CFSTR("/Library/Frameworks/SASL2.framework"), 0,
true );
if ( saslcfmglob.bundleURL != NULL )
saslcfmglob.myBundle = CFBundleCreate(
NULL , saslcfmglob.bundleURL );
if ( saslcfmglob.myBundle && CFBundleLoadExecutable( saslcfmglob.myBundle )) {
saslcfmglob.SASLClientNewPtr = (void*)CFBundleGetFunctionPointerForName(
saslcfmglob.myBundle, CFSTR("sasl_client_new") );
saslcfmglob.SASLClientStartPtr = (void*)CFBundleGetFunctionPointerForName(
saslcfmglob.myBundle, CFSTR("sasl_client_start") );
saslcfmglob.SASLClientStepPtr = (void*)CFBundleGetFunctionPointerForName(
saslcfmglob.myBundle, CFSTR("sasl_client_step") );
saslcfmglob.SASLErrStringPtr = (void*)CFBundleGetFunctionPointerForName(
saslcfmglob.myBundle, CFSTR("sasl_errstring") );
saslcfmglob.sasl_errdetailPtr = (void*)CFBundleGetFunctionPointerForName(
saslcfmglob.myBundle, CFSTR("sasl_errdetail") );
saslcfmglob.SASLGetPropPtr = (void*)CFBundleGetFunctionPointerForName(
saslcfmglob.myBundle, CFSTR("sasl_getprop") );
saslcfmglob.SASLSetPropPtr = (void*)CFBundleGetFunctionPointerForName(
saslcfmglob.myBundle, CFSTR("sasl_setprop") );
saslcfmglob.SASLIdlePtr = (void*)CFBundleGetFunctionPointerForName(
saslcfmglob.myBundle, CFSTR("sasl_idle") );
saslcfmglob.SASLEncodePtr = (void*)CFBundleGetFunctionPointerForName(
saslcfmglob.myBundle, CFSTR("sasl_encode") );
saslcfmglob.SASLEncodeVPtr = (void*)CFBundleGetFunctionPointerForName(
saslcfmglob.myBundle, CFSTR("sasl_encodev") );
saslcfmglob.SASLDecodePtr = (void*)CFBundleGetFunctionPointerForName(
saslcfmglob.myBundle, CFSTR("sasl_decode") );
saslcfmglob.SASLDisposePtr = (void*)CFBundleGetFunctionPointerForName(
saslcfmglob.myBundle, CFSTR("sasl_dispose") );
saslcfmglob.SASLDonePtr = (void*)CFBundleGetFunctionPointerForName(
saslcfmglob.myBundle, CFSTR("sasl_done") );
saslcfmglob.SASLSetAllocPtr = (void*)CFBundleGetFunctionPointerForName(
saslcfmglob.myBundle, CFSTR("sasl_set_alloc") );
saslcfmglob.sasl_encode64Ptr = (void*)CFBundleGetFunctionPointerForName(
saslcfmglob.myBundle, CFSTR("sasl_encode64") );
saslcfmglob.sasl_decode64Ptr = (void*)CFBundleGetFunctionPointerForName(
saslcfmglob.myBundle, CFSTR("sasl_decode64") );
saslcfmglob.sasl_mkchalPtr = (void*)CFBundleGetFunctionPointerForName(
saslcfmglob.myBundle, CFSTR("sasl_mkchal") );
saslcfmglob.sasl_utf8verifyPtr = (void*)CFBundleGetFunctionPointerForName(
saslcfmglob.myBundle, CFSTR("sasl_utf8verify") );
saslcfmglob.sasl_churnPtr = (void*)CFBundleGetFunctionPointerForName(
saslcfmglob.myBundle, CFSTR("sasl_churn") );
saslcfmglob.sasl_randPtr = (void*)CFBundleGetFunctionPointerForName(
saslcfmglob.myBundle, CFSTR("sasl_rand") );
saslcfmglob.sasl_randseedPtr = (void*)CFBundleGetFunctionPointerForName(
saslcfmglob.myBundle, CFSTR("sasl_randseed") );
saslcfmglob.sasl_randcreatePtr = (void*)CFBundleGetFunctionPointerForName(
saslcfmglob.myBundle, CFSTR("sasl_randcreate") );
saslcfmglob.sasl_randfreePtr = (void*)CFBundleGetFunctionPointerForName(
saslcfmglob.myBundle, CFSTR("sasl_randfree") );
saslcfmglob.SASLSetMutexPtr = (void*)CFBundleGetFunctionPointerForName(
saslcfmglob.myBundle, CFSTR("sasl_set_mutex") );
saslcfmglob.SASLServerNewPtr = (void*)CFBundleGetFunctionPointerForName(
saslcfmglob.myBundle, CFSTR("sasl_server_new") );
saslcfmglob.SASLServerStartPtr = (void*)CFBundleGetFunctionPointerForName(
saslcfmglob.myBundle, CFSTR("sasl_server_start") );
saslcfmglob.SASLServerStepPtr = (void*)CFBundleGetFunctionPointerForName(
saslcfmglob.myBundle, CFSTR("sasl_server_step") );
saslcfmglob.sasl_listmechPtr = (void*)CFBundleGetFunctionPointerForName(
saslcfmglob.myBundle, CFSTR("sasl_listmech") );
saslcfmglob.sasl_checkpassPtr = (void*)CFBundleGetFunctionPointerForName(
saslcfmglob.myBundle, CFSTR("sasl_checkpass") );
saslcfmglob.sasl_setpassPtr = (void*)CFBundleGetFunctionPointerForName(
saslcfmglob.myBundle, CFSTR("sasl_setpass") );
saslcfmglob.sasl_user_existsPtr = (void*)CFBundleGetFunctionPointerForName(
saslcfmglob.myBundle, CFSTR("sasl_user_exists") );
saslcfmglob.sasl_checkapopPtr = (void*)CFBundleGetFunctionPointerForName(
saslcfmglob.myBundle, CFSTR("sasl_checkapop") );
saslcfmglob.sasl_auxprop_requestPtr = (void*)CFBundleGetFunctionPointerForName(
saslcfmglob.myBundle, CFSTR("sasl_auxprop_request") );
saslcfmglob.sasl_auxprop_getctxPtr = (void*)CFBundleGetFunctionPointerForName(
saslcfmglob.myBundle, CFSTR("sasl_auxprop_getctx") );
saslcfmglob.sasl_erasebufferPtr = (void*)CFBundleGetFunctionPointerForName(
saslcfmglob.myBundle, CFSTR("sasl_erasebuffer") );
saslcfmglob.prop_newPtr = (void*)CFBundleGetFunctionPointerForName(
saslcfmglob.myBundle, CFSTR("prop_new") );
saslcfmglob.prop_dupPtr = (void*)CFBundleGetFunctionPointerForName(
saslcfmglob.myBundle, CFSTR("prop_dup") );
saslcfmglob.prop_getPtr = (void*)CFBundleGetFunctionPointerForName(
saslcfmglob.myBundle, CFSTR("prop_get") );
saslcfmglob.prop_getnamesPtr = (void*)CFBundleGetFunctionPointerForName(
saslcfmglob.myBundle, CFSTR("prop_getnames") );
saslcfmglob.prop_clearPtr = (void*)CFBundleGetFunctionPointerForName(
saslcfmglob.myBundle, CFSTR("prop_clear") );
saslcfmglob.prop_erasePtr = (void*)CFBundleGetFunctionPointerForName(
saslcfmglob.myBundle, CFSTR("prop_erase") );
saslcfmglob.prop_disposePtr = (void*)CFBundleGetFunctionPointerForName(
saslcfmglob.myBundle, CFSTR("prop_dispose") );
saslcfmglob.prop_formatPtr = (void*)CFBundleGetFunctionPointerForName(
saslcfmglob.myBundle, CFSTR("prop_format") );
saslcfmglob.prop_setPtr = (void*)CFBundleGetFunctionPointerForName(
saslcfmglob.myBundle, CFSTR("prop_set") );
saslcfmglob.prop_setvalsPtr = (void*)CFBundleGetFunctionPointerForName(
saslcfmglob.myBundle, CFSTR("prop_setvals") );
saslcfmglob._sasl_add_stringPtr = (void*)CFBundleGetFunctionPointerForName(
saslcfmglob.myBundle, CFSTR("_sasl_add_string") );
saslcfmglob._buf_allocPtr = (void*)CFBundleGetFunctionPointerForName(
saslcfmglob.myBundle, CFSTR("_buf_alloc") );
saslcfmglob._sasl_get_errorbufPtr = (void*)CFBundleGetFunctionPointerForName(
saslcfmglob.myBundle, CFSTR("_sasl_get_errorbuf") );
if (!_cfmsasl_haveCustomAlloc) {
saslcfmglobp.custMalloc = MachOFunctionPointerForCFMFunctionPointer(malloc);
saslcfmglobp.custCalloc = MachOFunctionPointerForCFMFunctionPointer(calloc);
saslcfmglobp.custRealloc = MachOFunctionPointerForCFMFunctionPointer(realloc);
saslcfmglobp.custFree = MachOFunctionPointerForCFMFunctionPointer(free);
_cfmsasl_haveCustomAlloc = 1;
}
saslcfmglob.SASLSetAllocPtr(saslcfmglobp.custMalloc, saslcfmglobp.custCalloc,
saslcfmglobp.custRealloc, saslcfmglobp.custFree);
if (_cfmsasl_haveCustomMutex)
saslcfmglob.SASLSetMutexPtr(saslcfmglobp.custMutexNew, saslcfmglobp.custMutexLock,
saslcfmglobp.custMutexUnlock, saslcfmglobp.custMutexDispose);
} else if (saslcfmglob.myBundle) {
CFRelease(saslcfmglob.myBundle);
saslcfmglob.myBundle = nil;
}
if (saslcfmglob.bundleURL && !saslcfmglob.myBundle) {
CFRelease(saslcfmglob.bundleURL);
saslcfmglob.bundleURL = nil;
}
if (saslcfmglob.myBundle)
_cfmsasl_initted = 1;
}
if (_cfmsasl_initted) {
if (isServer) {
SASLServerInitPtr = (void*)CFBundleGetFunctionPointerForName(
saslcfmglob.myBundle, CFSTR("sasl_server_init") );
if (SASLServerInitPtr != nil) {
sasl_callback_t *new_callbacks = NULL;
if (callbacks)
new_callbacks = GetCFMCallbacks(callbacks);
result = SASLServerInitPtr(new_callbacks, appname);
saslcfmglob.serverCallbacks = new_callbacks;
}
} else {
SASLClientInitPtr = (void*)CFBundleGetFunctionPointerForName(
saslcfmglob.myBundle, CFSTR("sasl_client_init") );
if (SASLClientInitPtr != nil) {
sasl_callback_t *new_callbacks = NULL;
if (callbacks)
new_callbacks = GetCFMCallbacks(callbacks);
result = SASLClientInitPtr(new_callbacks);
saslcfmglob.clientCallbacks = new_callbacks;
}
}
}
return result;
}
int sasl_server_init(const sasl_callback_t *callbacks,
const char *appname)
{
return _cfmsasl_common_init(callbacks, true, appname);
}
int sasl_client_init(const sasl_callback_t *callbacks)
{
return _cfmsasl_common_init(callbacks, false, nil);
}
void sasl_done(void)
{
if (!_cfmsasl_initted)
return;
if (!saslcfmglob.SASLDonePtr) return;
saslcfmglob.SASLDonePtr();
DisposeCFMCallbacks(saslcfmglob.clientCallbacks);
DisposeCFMCallbacks(saslcfmglob.serverCallbacks);
CFBundleUnloadExecutable(saslcfmglob.myBundle);
CFRelease(saslcfmglob.myBundle);
CFRelease(saslcfmglob.bundleURL);
saslcfmglob.myBundle = NULL;
saslcfmglob.bundleURL = NULL;
_cfmsasl_initted = 0;
}
int 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)
{
sasl_callback_t *new_ps = NULL;
int result;
cfm_sasl_conn_t *myconn;
if (!_cfmsasl_initted)
return SASL_NOMEM;
if (!saslcfmglob.SASLClientNewPtr) return SASL_NOMEM;
if (prompt_supp)
new_ps = GetCFMCallbacks(prompt_supp);
myconn = (cfm_sasl_conn_t *) NewPtr(sizeof(cfm_sasl_conn_t));
if (myconn == NULL) {
return SASL_NOMEM;
}
myconn->ctx = NULL;
result = saslcfmglob.SASLClientNewPtr(service, serverFQDN, iplocalport,
ipremoteport, new_ps, flags,
&(myconn->ctx));
myconn->cbk = new_ps;
*pconn = (sasl_conn_t *)myconn;
return result;
}
int 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)
{
sasl_callback_t *new_ps = NULL;
int result;
if (!_cfmsasl_initted)
return SASL_NOMEM;
if (!saslcfmglob.SASLServerNewPtr) return SASL_NOMEM;
if (callbacks)
new_ps = GetCFMCallbacks(callbacks);
*pconn = (sasl_conn_t *)NewPtr(sizeof(cfm_sasl_conn_t));
((cfm_sasl_conn_t *)*pconn)->ctx = nil;
result = saslcfmglob.SASLServerNewPtr(service, serverFQDN, user_realm,
iplocalport, ipremoteport, new_ps, flags,
&((cfm_sasl_conn_t *)*pconn)->ctx);
((cfm_sasl_conn_t *)*pconn)->cbk = new_ps;
return result;
}
void sasl_dispose(sasl_conn_t **pconn)
{
if (!_cfmsasl_initted)
return;
if (!saslcfmglob.SASLDisposePtr) return;
if (!pconn) return;
if (!*pconn) return;
saslcfmglob.SASLDisposePtr(&((cfm_sasl_conn_t *)*pconn)->ctx);
DisposeCFMCallbacks(((cfm_sasl_conn_t *)*pconn)->cbk);
DisposePtr((Ptr)*pconn);
*pconn = NULL;
}
int sasl_client_start (sasl_conn_t *conn,
const char *mechlist,
sasl_interact_t **prompt_need,
const char **clientout,
unsigned *clientoutlen,
const char **mech)
{
if (!_cfmsasl_initted)
return SASL_NOMEM;
if (!saslcfmglob.SASLClientStartPtr) return SASL_NOMEM;
return saslcfmglob.SASLClientStartPtr(((cfm_sasl_conn_t *)conn)->ctx, mechlist,
prompt_need, clientout, clientoutlen, mech);
}
int sasl_client_step (sasl_conn_t *conn,
const char *serverin,
unsigned serverinlen,
sasl_interact_t **prompt_need,
const char **clientout,
unsigned *clientoutlen)
{
if (!_cfmsasl_initted)
return SASL_NOMEM;
if (!saslcfmglob.SASLClientStepPtr) return SASL_NOMEM;
return saslcfmglob.SASLClientStepPtr(((cfm_sasl_conn_t *)conn)->ctx, serverin,
serverinlen, prompt_need, clientout, clientoutlen);
}
const char *sasl_errstring(int saslerr,
const char *langlist,
const char **outlang)
{
if (!_cfmsasl_initted)
return NULL;
if (!saslcfmglob.SASLErrStringPtr) return NULL;
return saslcfmglob.SASLErrStringPtr(saslerr, langlist, outlang);
}
const char *sasl_errdetail(sasl_conn_t *conn)
{
if (!_cfmsasl_initted)
return NULL;
if (!saslcfmglob.sasl_errdetailPtr) return NULL;
return saslcfmglob.sasl_errdetailPtr(((cfm_sasl_conn_t *)conn)->ctx);
}
int sasl_getprop(sasl_conn_t *conn, int propnum, const void **pvalue)
{
if (!_cfmsasl_initted)
return SASL_NOMEM;
if (!saslcfmglob.SASLGetPropPtr) return SASL_NOMEM;
return saslcfmglob.SASLGetPropPtr(((cfm_sasl_conn_t *)conn)->ctx, propnum, pvalue);
}
int sasl_setprop(sasl_conn_t *conn,
int propnum,
const void *value)
{
if (!_cfmsasl_initted)
return SASL_NOMEM;
if (!saslcfmglob.SASLSetPropPtr) return SASL_NOMEM;
return saslcfmglob.SASLSetPropPtr(((cfm_sasl_conn_t *)conn)->ctx, propnum, value);
}
int sasl_idle(sasl_conn_t *conn)
{
if (!_cfmsasl_initted)
return SASL_NOMEM;
if (!saslcfmglob.SASLIdlePtr) return SASL_NOMEM;
return saslcfmglob.SASLIdlePtr(((cfm_sasl_conn_t *)conn)->ctx);
}
int sasl_encode(sasl_conn_t *conn,
const char *input, unsigned inputlen,
const char **output, unsigned *outputlen)
{
if (!_cfmsasl_initted)
return SASL_NOMEM;
if (!saslcfmglob.SASLEncodePtr) return SASL_NOMEM;
return saslcfmglob.SASLEncodePtr(((cfm_sasl_conn_t *)conn)->ctx, input, inputlen,
output, outputlen);
}
int sasl_encodev(sasl_conn_t *conn,
const struct iovec *invec, unsigned numiov,
const char **output, unsigned *outputlen)
{
if (!_cfmsasl_initted)
return SASL_NOMEM;
if (!saslcfmglob.SASLEncodeVPtr) return SASL_NOMEM;
return saslcfmglob.SASLEncodeVPtr(((cfm_sasl_conn_t *)conn)->ctx, invec, numiov,
output, outputlen);
}
int sasl_decode(sasl_conn_t *conn,
const char *input, unsigned inputlen,
const char **output, unsigned *outputlen)
{
if (!_cfmsasl_initted)
return SASL_NOMEM;
if (!saslcfmglob.SASLDecodePtr) return SASL_NOMEM;
return saslcfmglob.SASLDecodePtr(((cfm_sasl_conn_t *)conn)->ctx, input, inputlen,
output, outputlen);
}
int sasl_decode64(const char *in, unsigned inlen,
char *out, unsigned outmax, unsigned *outlen)
{
if (!_cfmsasl_initted)
return SASL_NOMEM;
if (!saslcfmglob.sasl_decode64Ptr) return SASL_NOMEM;
return saslcfmglob.sasl_decode64Ptr(in, inlen, out, outmax, outlen);
}
int sasl_encode64(const char *in, unsigned inlen,
char *out, unsigned outmax, unsigned *outlen)
{
if (!_cfmsasl_initted)
return SASL_NOMEM;
if (!saslcfmglob.sasl_encode64Ptr) return SASL_NOMEM;
return saslcfmglob.sasl_encode64Ptr(in, inlen, out, outmax, outlen);
}
void sasl_set_alloc(sasl_malloc_t *ma, sasl_calloc_t *ca, sasl_realloc_t *rea, sasl_free_t *fr)
{
if (_cfmsasl_haveCustomAlloc) {
DisposePtr((Ptr)saslcfmglobp.custMalloc);
DisposePtr((Ptr)saslcfmglobp.custCalloc);
DisposePtr((Ptr)saslcfmglobp.custRealloc);
DisposePtr((Ptr)saslcfmglobp.custFree);
}
saslcfmglobp.custMalloc = MachOFunctionPointerForCFMFunctionPointer(ma);
saslcfmglobp.custCalloc = MachOFunctionPointerForCFMFunctionPointer(ca);
saslcfmglobp.custRealloc = MachOFunctionPointerForCFMFunctionPointer(rea);
saslcfmglobp.custFree = MachOFunctionPointerForCFMFunctionPointer(fr);
_cfmsasl_haveCustomAlloc = 1;
}
int sasl_mkchal(sasl_conn_t *conn, char *buf,
unsigned maxlen, unsigned hostflag)
{
if (!_cfmsasl_initted)
return SASL_NOMEM;
if (!saslcfmglob.sasl_mkchalPtr) return SASL_NOMEM;
return saslcfmglob.sasl_mkchalPtr(((cfm_sasl_conn_t *)conn)->ctx, buf, maxlen, hostflag);
}
int sasl_utf8verify(const char *str, unsigned len)
{
if (!_cfmsasl_initted)
return SASL_NOMEM;
if (!saslcfmglob.sasl_utf8verifyPtr) return SASL_NOMEM;
return saslcfmglob.sasl_utf8verifyPtr(str, len);
}
void sasl_churn(sasl_rand_t *rpool,
const char *data,
unsigned len)
{
if (!_cfmsasl_initted)
return;
if (!saslcfmglob.sasl_churnPtr) return;
saslcfmglob.sasl_churnPtr(rpool, data, len);
}
void sasl_rand(sasl_rand_t *rpool,
char *buf,
unsigned len)
{
if (!_cfmsasl_initted)
return;
if (!saslcfmglob.sasl_randPtr) return;
saslcfmglob.sasl_randPtr(rpool, buf, len);
}
void sasl_randseed(sasl_rand_t *rpool,
const char *seed,
unsigned len)
{
if (!_cfmsasl_initted)
return;
if (!saslcfmglob.sasl_randseedPtr) return;
saslcfmglob.sasl_randseedPtr(rpool, seed, len);
}
void sasl_randfree(sasl_rand_t **rpool)
{
if (!_cfmsasl_initted)
return;
if (!saslcfmglob.sasl_randfreePtr) return;
saslcfmglob.sasl_randfreePtr(rpool);
}
int sasl_randcreate(sasl_rand_t **rpool)
{
if (!_cfmsasl_initted)
return SASL_NOMEM;
if (!saslcfmglob.sasl_randcreatePtr) return SASL_NOMEM;
return saslcfmglob.sasl_randcreatePtr(rpool);
}
void sasl_set_mutex(sasl_mutex_alloc_t *mn, sasl_mutex_lock_t *ml,
sasl_mutex_unlock_t *mu, sasl_mutex_free_t *md)
{
if (_cfmsasl_haveCustomMutex) {
DisposePtr((Ptr)saslcfmglobp.custMutexNew);
DisposePtr((Ptr)saslcfmglobp.custMutexLock);
DisposePtr((Ptr)saslcfmglobp.custMutexUnlock);
DisposePtr((Ptr)saslcfmglobp.custMutexDispose);
}
saslcfmglobp.custMutexNew = MachOFunctionPointerForCFMFunctionPointer(mn);
saslcfmglobp.custMutexLock = MachOFunctionPointerForCFMFunctionPointer(ml);
saslcfmglobp.custMutexUnlock = MachOFunctionPointerForCFMFunctionPointer(mu);
saslcfmglobp.custMutexDispose = MachOFunctionPointerForCFMFunctionPointer(md);
_cfmsasl_haveCustomMutex = 1;
}
int 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)
{
if (!_cfmsasl_initted)
return SASL_NOMEM;
if (!saslcfmglob.sasl_listmechPtr) return SASL_NOMEM;
return saslcfmglob.sasl_listmechPtr(((cfm_sasl_conn_t *)conn)->ctx, user, prefix, sep,
suffix, result, plen, pcount);
}
int sasl_server_start(sasl_conn_t *conn,
const char *mech,
const char *clientin,
unsigned clientinlen,
const char **serverout,
unsigned *serveroutlen)
{
if (!_cfmsasl_initted)
return SASL_NOMEM;
if (!saslcfmglob.SASLServerStartPtr) return SASL_NOMEM;
return saslcfmglob.SASLServerStartPtr(((cfm_sasl_conn_t *)conn)->ctx, mech, clientin,
clientinlen, serverout, serveroutlen);
}
int sasl_server_step(sasl_conn_t *conn,
const char *clientin,
unsigned clientinlen,
const char **serverout,
unsigned *serveroutlen)
{
if (!_cfmsasl_initted)
return SASL_NOMEM;
if (!saslcfmglob.SASLServerStepPtr) return SASL_NOMEM;
return saslcfmglob.SASLServerStepPtr(((cfm_sasl_conn_t *)conn)->ctx, clientin, clientinlen,
serverout, serveroutlen);
}
int sasl_checkpass(sasl_conn_t *conn,
const char *user,
unsigned userlen,
const char *pass,
unsigned passlen)
{
if (!_cfmsasl_initted)
return SASL_NOMEM;
if (!saslcfmglob.sasl_checkpassPtr) return SASL_NOMEM;
return saslcfmglob.sasl_checkpassPtr(((cfm_sasl_conn_t *)conn)->ctx, user, userlen, pass,
passlen);
}
int sasl_user_exists(sasl_conn_t *conn,
const char *service,
const char *user_realm,
const char *user)
{
if (!_cfmsasl_initted)
return SASL_NOMEM;
if (!saslcfmglob.sasl_user_existsPtr) return SASL_NOMEM;
return saslcfmglob.sasl_user_existsPtr(((cfm_sasl_conn_t *)conn)->ctx,
service, user_realm, user);
}
int sasl_setpass(sasl_conn_t *conn,
const char *user,
const char *pass,
unsigned passlen,
const char *oldpass, unsigned oldpasslen,
unsigned flags)
{
if (!_cfmsasl_initted)
return SASL_NOMEM;
if (!saslcfmglob.sasl_setpassPtr) return SASL_NOMEM;
return saslcfmglob.sasl_setpassPtr(((cfm_sasl_conn_t *)conn)->ctx, user, pass,
passlen, oldpass, oldpasslen, flags);
}
int sasl_checkapop(sasl_conn_t *conn,
const char *challenge, unsigned challen,
const char *response, unsigned resplen)
{
if (!_cfmsasl_initted)
return SASL_NOMEM;
if (!saslcfmglob.sasl_checkapopPtr) return SASL_NOMEM;
return saslcfmglob.sasl_checkapopPtr(((cfm_sasl_conn_t *)conn)->ctx, challenge, challen,
response, resplen);
}
int sasl_auxprop_request(sasl_conn_t *conn,
const char **propnames)
{
if (!_cfmsasl_initted)
return SASL_NOMEM;
if (!saslcfmglob.sasl_auxprop_requestPtr) return SASL_NOMEM;
return saslcfmglob.sasl_auxprop_requestPtr(((cfm_sasl_conn_t *)conn)->ctx, propnames);
}
struct propctx *sasl_auxprop_getctx(sasl_conn_t *conn)
{
if (!_cfmsasl_initted)
return NULL;
if (!saslcfmglob.sasl_auxprop_getctxPtr) return NULL;
return saslcfmglob.sasl_auxprop_getctxPtr(((cfm_sasl_conn_t *)conn)->ctx);
}
void sasl_erasebuffer(char *pass, unsigned len)
{
if (!_cfmsasl_initted)
return;
if (!saslcfmglob.sasl_erasebufferPtr) return;
saslcfmglob.sasl_erasebufferPtr(pass, len);
}
struct propctx *prop_new(unsigned estimate)
{
if (!_cfmsasl_initted)
return NULL;
if (!saslcfmglob.prop_newPtr) return NULL;
return saslcfmglob.prop_newPtr(estimate);
}
int prop_dup(struct propctx *src_ctx, struct propctx **dst_ctx)
{
if (!_cfmsasl_initted)
return SASL_NOMEM;
if (!saslcfmglob.prop_dupPtr) return SASL_NOMEM;
return saslcfmglob.prop_dupPtr(src_ctx, dst_ctx);
}
const struct propval *prop_get(struct propctx *ctx)
{
if (!_cfmsasl_initted)
return NULL;
if (!saslcfmglob.prop_getPtr) return NULL;
return saslcfmglob.prop_getPtr(ctx);
}
int prop_getnames(struct propctx *ctx, const char **names,
struct propval *vals)
{
if (!_cfmsasl_initted)
return SASL_NOMEM;
if (!saslcfmglob.prop_getnamesPtr) return SASL_NOMEM;
return saslcfmglob.prop_getnamesPtr(ctx, names, vals);
}
void prop_clear(struct propctx *ctx, int requests)
{
if (!_cfmsasl_initted)
return;
if (!saslcfmglob.prop_clearPtr) return;
saslcfmglob.prop_clearPtr(ctx, requests);
}
void prop_erase(struct propctx *ctx, const char *name)
{
if (!_cfmsasl_initted)
return;
if (!saslcfmglob.prop_erasePtr) return;
saslcfmglob.prop_erasePtr(ctx, name);
}
void prop_dispose(struct propctx **ctx)
{
if (!_cfmsasl_initted)
return;
if (!saslcfmglob.prop_disposePtr) return;
saslcfmglob.prop_disposePtr(ctx);
}
int prop_format(struct propctx *ctx, const char *sep, int seplen,
char *outbuf, unsigned outmax, unsigned *outlen)
{
if (!_cfmsasl_initted)
return SASL_NOMEM;
if (!saslcfmglob.prop_formatPtr) return SASL_NOMEM;
return saslcfmglob.prop_formatPtr(ctx, sep, seplen, outbuf, outmax, outlen);
}
int prop_set(struct propctx *ctx, const char *name,
const char *value, int vallen)
{
if (!_cfmsasl_initted)
return SASL_NOMEM;
if (!saslcfmglob.prop_setPtr) return SASL_NOMEM;
return saslcfmglob.prop_setPtr(ctx, name, value, vallen);
}
int prop_setvals(struct propctx *ctx, const char *name,
const char **values)
{
if (!_cfmsasl_initted)
return SASL_NOMEM;
if (!saslcfmglob.prop_setvalsPtr) return SASL_NOMEM;
return saslcfmglob.prop_setvalsPtr(ctx, name, values);
}
int _sasl_add_string(char **out, int *alloclen, int *outlen, const char *add)
{
if (!_cfmsasl_initted)
return SASL_NOMEM;
if (!saslcfmglob._sasl_add_stringPtr) return SASL_NOMEM;
return saslcfmglob._sasl_add_stringPtr(out, alloclen, outlen, add);
}
int _buf_alloc(char **rwbuf, unsigned *curlen, unsigned newlen)
{
if (!_cfmsasl_initted)
return SASL_NOMEM;
if (!saslcfmglob._buf_allocPtr) return SASL_NOMEM;
return saslcfmglob._buf_allocPtr(rwbuf, curlen, newlen);
}
void _sasl_get_errorbuf(sasl_conn_t *conn, char ***bufhdl, unsigned **lenhdl)
{
if (!_cfmsasl_initted)
return;
if (!saslcfmglob._sasl_add_stringPtr) return;
saslcfmglob._sasl_get_errorbufPtr(((cfm_sasl_conn_t *)conn)->ctx, bufhdl, lenhdl);
}