Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-02-21 10:15:32

0001 /* saslplug.h --  API for SASL plug-ins
0002  */
0003 
0004 #ifndef SASLPLUG_H
0005 #define SASLPLUG_H 1
0006 
0007 #ifndef MD5GLOBAL_H
0008 #include "md5global.h"
0009 #endif
0010 #ifndef MD5_H
0011 #include "md5.h"
0012 #endif
0013 #ifndef HMAC_MD5_H
0014 #include "hmac-md5.h"
0015 #endif
0016 #ifndef PROP_H
0017 #include "prop.h"
0018 #endif
0019 
0020 #ifdef __cplusplus
0021 extern "C" {
0022 #endif
0023 
0024 /* callback to lookup a sasl_callback_t for a connection
0025  * input:
0026  *  conn        -- the connection to lookup a callback for
0027  *  callbacknum -- the number of the callback
0028  * output:
0029  *  pproc       -- pointer to the callback function (set to NULL on failure)
0030  *  pcontext    -- pointer to the callback context (set to NULL on failure)
0031  * returns:
0032  *  SASL_OK -- no error
0033  *  SASL_FAIL -- unable to find a callback of the requested type
0034  *  SASL_INTERACT -- caller must use interaction to get data
0035  */
0036 typedef int (*sasl_callback_ft)(void);
0037 typedef int sasl_getcallback_t(sasl_conn_t *conn,
0038                    unsigned long callbackid,
0039                    sasl_callback_ft * pproc,
0040                    void **pcontext);
0041 
0042 /* The sasl_utils structure will remain backwards compatible unless
0043  * the SASL_*_PLUG_VERSION is changed incompatibly
0044  * higher SASL_UTILS_VERSION numbers indicate more functions are available
0045  */
0046 #define SASL_UTILS_VERSION 4
0047 
0048 /* utility function set for plug-ins
0049  */
0050 typedef struct sasl_utils {
0051     int version;
0052 
0053     /* contexts */
0054     sasl_conn_t *conn;
0055     sasl_rand_t *rpool;
0056     void *getopt_context;
0057 
0058     /* option function */
0059     sasl_getopt_t *getopt;
0060     
0061     /* allocation functions: */
0062     sasl_malloc_t *malloc;
0063     sasl_calloc_t *calloc;
0064     sasl_realloc_t *realloc;
0065     sasl_free_t *free;
0066 
0067     /* mutex functions: */
0068     sasl_mutex_alloc_t *mutex_alloc;
0069     sasl_mutex_lock_t *mutex_lock;
0070     sasl_mutex_unlock_t *mutex_unlock;
0071     sasl_mutex_free_t *mutex_free;
0072 
0073     /* MD5 hash and HMAC functions */
0074     void (*MD5Init)(MD5_CTX *);
0075     void (*MD5Update)(MD5_CTX *, const unsigned char *text, unsigned int len);
0076     void (*MD5Final)(unsigned char [16], MD5_CTX *);
0077     void (*hmac_md5)(const unsigned char *text, int text_len,
0078              const unsigned char *key, int key_len,
0079              unsigned char [16]);
0080     void (*hmac_md5_init)(HMAC_MD5_CTX *, const unsigned char *key, int len);
0081     /* hmac_md5_update() is just a call to MD5Update on inner context */
0082     void (*hmac_md5_final)(unsigned char [16], HMAC_MD5_CTX *);
0083     void (*hmac_md5_precalc)(HMAC_MD5_STATE *,
0084                  const unsigned char *key, int len);
0085     void (*hmac_md5_import)(HMAC_MD5_CTX *, HMAC_MD5_STATE *);
0086 
0087     /* mechanism utility functions (same as above): */
0088     int (*mkchal)(sasl_conn_t *conn, char *buf, unsigned maxlen,
0089           unsigned hostflag);
0090     int (*utf8verify)(const char *str, unsigned len);
0091     void (*rand)(sasl_rand_t *rpool, char *buf, unsigned len);
0092     void (*churn)(sasl_rand_t *rpool, const char *data, unsigned len);
0093 
0094     /* This allows recursive calls to the sasl_checkpass() routine from
0095      * within a SASL plug-in.  This MUST NOT be used in the PLAIN mechanism
0096      * as sasl_checkpass MAY be a front-end for the PLAIN mechanism.
0097      * This is intended for use by the non-standard LOGIN mechanism and
0098      * potentially by a future mechanism which uses public-key technology to
0099      * set up a lightweight encryption layer just for sending a password.
0100      */
0101     int (*checkpass)(sasl_conn_t *conn,
0102              const char *user, unsigned userlen,
0103              const char *pass, unsigned passlen);
0104     
0105     /* Access to base64 encode/decode routines */
0106     int (*decode64)(const char *in, unsigned inlen,
0107             char *out, unsigned outmax, unsigned *outlen);
0108     int (*encode64)(const char *in, unsigned inlen,
0109             char *out, unsigned outmax, unsigned *outlen);
0110 
0111     /* erase a buffer */
0112     void (*erasebuffer)(char *buf, unsigned len);
0113 
0114     /* callback to sasl_getprop() and sasl_setprop() */
0115     int (*getprop)(sasl_conn_t *conn, int propnum, const void **pvalue);
0116     int (*setprop)(sasl_conn_t *conn, int propnum, const void *value);
0117 
0118     /* callback function */
0119     sasl_getcallback_t *getcallback;
0120 
0121     /* format a message and then pass it to the SASL_CB_LOG callback
0122      *
0123      * use syslog()-style formatting (printf with %m as a human readable text
0124      * (strerror()) for the error specified as the parameter).
0125      * The implementation may use a fixed size buffer not smaller
0126      * than 512 octets if it securely truncates the message.
0127      *
0128      * level is a SASL_LOG_* level (see sasl.h)
0129      */
0130     void (*log)(sasl_conn_t *conn, int level, const char *fmt, ...) __attribute__((format(printf, 3, 4)));
0131 
0132     /* callback to sasl_seterror() */
0133     void (*seterror)(sasl_conn_t *conn, unsigned flags, const char *fmt, ...) __attribute__((format(printf, 3, 4)));
0134 
0135     /* spare function pointer */
0136     int *(*spare_fptr)(void);
0137 
0138     /* auxiliary property utilities */
0139     struct propctx *(*prop_new)(unsigned estimate);
0140     int (*prop_dup)(struct propctx *src_ctx, struct propctx **dst_ctx);
0141     int (*prop_request)(struct propctx *ctx, const char **names);
0142     const struct propval *(*prop_get)(struct propctx *ctx);
0143     int (*prop_getnames)(struct propctx *ctx, const char **names,
0144              struct propval *vals);
0145     void (*prop_clear)(struct propctx *ctx, int requests);
0146     void (*prop_dispose)(struct propctx **ctx);
0147     int (*prop_format)(struct propctx *ctx, const char *sep, int seplen,
0148                char *outbuf, unsigned outmax, unsigned *outlen);
0149     int (*prop_set)(struct propctx *ctx, const char *name,
0150             const char *value, int vallen);
0151     int (*prop_setvals)(struct propctx *ctx, const char *name,
0152             const char **values);
0153     void (*prop_erase)(struct propctx *ctx, const char *name);
0154     int (*auxprop_store)(sasl_conn_t *conn,
0155              struct propctx *ctx, const char *user);
0156 
0157     /* for additions which don't require a version upgrade; set to 0 */
0158     int (*spare_fptr1)(void);
0159     int (*spare_fptr2)(void);
0160 } sasl_utils_t;
0161 
0162 /*
0163  * output parameters from SASL API
0164  *
0165  * created / destroyed by the glue code, though probably filled in
0166  * by a combination of the plugin, the glue code, and the canon_user callback.
0167  *
0168  */
0169 typedef struct sasl_out_params {
0170     unsigned doneflag;      /* exchange complete */
0171 
0172     const char *user;       /* canonicalized user name */
0173     const char *authid;     /* canonicalized authentication id */
0174 
0175     unsigned ulen;      /* length of canonicalized user name */
0176     unsigned alen;      /* length of canonicalized authid */
0177 
0178     /* security layer information */
0179     unsigned maxoutbuf;         /* Maximum buffer size, which will
0180                                    produce buffer no bigger than the
0181                                    negotiated SASL maximum buffer size */
0182     sasl_ssf_t mech_ssf;   /* Should be set non-zero if negotiation of a
0183                 * security layer was *attempted*, even if
0184                 * the negotiation failed */
0185     void *encode_context;
0186     int (*encode)(void *context, const struct iovec *invec, unsigned numiov,
0187           const char **output, unsigned *outputlen);
0188     void *decode_context;
0189     int (*decode)(void *context, const char *input, unsigned inputlen,
0190           const char **output, unsigned *outputlen);
0191     
0192     /* Pointer to delegated (client's) credentials, if supported by
0193        the SASL mechanism */
0194     void *client_creds;
0195 
0196     /* for additions which don't require a version upgrade; set to 0 */
0197     const void *gss_peer_name;
0198     const void *gss_local_name;
0199     const char *cbindingname;   /* channel binding name from packet */
0200     int (*spare_fptr1)(void);
0201     int (*spare_fptr2)(void);
0202     unsigned int cbindingdisp;  /* channel binding disposition from client */
0203     int spare_int2;
0204     int spare_int3;
0205     int spare_int4;
0206 
0207     /* set to 0 initially, this allows a plugin with extended parameters
0208      * to work with an older framework by updating version as parameters
0209      * are added.
0210      */
0211     int param_version;
0212 } sasl_out_params_t;
0213 
0214 
0215 
0216 /* Used by both client and server side plugins */
0217 typedef enum  {
0218     SASL_INFO_LIST_START = 0,
0219     SASL_INFO_LIST_MECH,
0220     SASL_INFO_LIST_END
0221 } sasl_info_callback_stage_t;
0222 
0223 /******************************
0224  * Channel binding macros     **
0225  ******************************/
0226 
0227 typedef enum {
0228     SASL_CB_DISP_NONE = 0,          /* client did not support CB */
0229     SASL_CB_DISP_WANT,              /* client supports CB, thinks server does not */
0230     SASL_CB_DISP_USED               /* client supports and used CB */
0231 } sasl_cbinding_disp_t;
0232 
0233 /* TRUE if channel binding is non-NULL */
0234 #define SASL_CB_PRESENT(params)     ((params)->cbinding != NULL)
0235 /* TRUE if channel binding is marked critical */
0236 #define SASL_CB_CRITICAL(params)    (SASL_CB_PRESENT(params) && \
0237                      (params)->cbinding->critical)
0238 
0239 /******************************
0240  * Client Mechanism Functions *
0241  ******************************/
0242 
0243 /*
0244  * input parameters to client SASL plugin
0245  *
0246  * created / destroyed by the glue code
0247  *
0248  */
0249 typedef struct sasl_client_params {
0250     const char *service;    /* service name */
0251     const char *serverFQDN; /* server fully qualified domain name */
0252     const char *clientFQDN; /* client's fully qualified domain name */
0253     const sasl_utils_t *utils;  /* SASL API utility routines --
0254                  * for a particular sasl_conn_t,
0255                  * MUST remain valid until mech_free is
0256                  * called */
0257     const sasl_callback_t *prompt_supp; /* client callback list */
0258     const char *iplocalport;    /* server IP domain literal & port */
0259     const char *ipremoteport;   /* client IP domain literal & port */
0260 
0261     unsigned servicelen;    /* length of service */
0262     unsigned slen;      /* length of serverFQDN */
0263     unsigned clen;      /* length of clientFQDN */
0264     unsigned iploclen;      /* length of iplocalport */
0265     unsigned ipremlen;      /* length of ipremoteport */
0266 
0267     /* application's security requirements & info */
0268     sasl_security_properties_t props;
0269     sasl_ssf_t external_ssf;    /* external SSF active */
0270 
0271     /* for additions which don't require a version upgrade; set to 0 */
0272     const void *gss_creds;                  /* GSS credential handle */
0273     const sasl_channel_binding_t *cbinding; /* client channel binding */
0274     const sasl_http_request_t *http_request;/* HTTP Digest request method */
0275     void *spare_ptr4;
0276 
0277     /* Canonicalize a user name from on-wire to internal format
0278      *  added rjs3 2001-05-23
0279      *  Must be called once user name aquired if canon_user is non-NULL.
0280      *  conn        connection context
0281      *  in          user name from wire protocol (need not be NUL terminated)
0282      *  len         length of user name from wire protocol (0 = strlen(user))
0283      *  flags       for SASL_CU_* flags
0284      *  oparams     the user, authid, ulen, alen, fields are
0285      *              set appropriately after canonicalization/copying and
0286      *              authorization of arguments
0287      *
0288      *  responsible for setting user, ulen, authid, and alen in the oparams
0289      *  structure
0290      *
0291      *  default behavior is to strip leading and trailing whitespace, as
0292      *  well as allocating space for and copying the parameters.
0293      *
0294      * results:
0295      *  SASL_OK       -- success
0296      *  SASL_NOMEM    -- out of memory
0297      *  SASL_BADPARAM -- invalid conn
0298      *  SASL_BADPROT  -- invalid user/authid
0299      */
0300     int (*canon_user)(sasl_conn_t *conn,
0301                     const char *in, unsigned len,
0302                     unsigned flags,
0303                     sasl_out_params_t *oparams);
0304 
0305     int (*spare_fptr1)(void);
0306 
0307     unsigned int cbindingdisp;
0308     int spare_int2;
0309     int spare_int3;
0310 
0311     /* flags field as passed to sasl_client_new */
0312     unsigned flags;
0313 
0314     /* set to 0 initially, this allows a plugin with extended parameters
0315      * to work with an older framework by updating version as parameters
0316      * are added.
0317      */
0318     int param_version;
0319 } sasl_client_params_t;
0320 
0321 /* features shared between client and server */
0322 /* These allow the glue code to handle client-first and server-last issues */
0323 
0324 /* This indicates that the mechanism prefers to do client-send-first
0325  * if the protocol allows it. */
0326 #define SASL_FEAT_WANT_CLIENT_FIRST 0x0002
0327 
0328 /* This feature is deprecated.  Instead, plugins should set *serverout to
0329  * non-NULL and return SASL_OK intelligently to allow flexible use of
0330  * server-last semantics
0331 #define SASL_FEAT_WANT_SERVER_LAST  0x0004
0332 */
0333 
0334 /* This feature is deprecated.  Instead, plugins should correctly set
0335  * SASL_FEAT_SERVER_FIRST as needed
0336 #define SASL_FEAT_INTERNAL_CLIENT_FIRST 0x0008
0337 */
0338 
0339 /* This indicates that the plugin is server-first only. 
0340  * Not defining either of SASL_FEAT_SERVER_FIRST or 
0341  * SASL_FEAT_WANT_CLIENT_FIRST indicates that the mechanism
0342  * will handle the client-first situation internally.
0343  */
0344 #define SASL_FEAT_SERVER_FIRST      0x0010
0345 
0346 /* This plugin allows proxying */
0347 #define SASL_FEAT_ALLOWS_PROXY      0x0020
0348 
0349 /* server plugin don't use cleartext userPassword attribute */
0350 #define SASL_FEAT_DONTUSE_USERPASSWD    0x0080
0351 
0352 /* Underlying mechanism uses GSS framing */
0353 #define SASL_FEAT_GSS_FRAMING       0x0100
0354 
0355 /* Underlying mechanism supports channel binding */
0356 #define SASL_FEAT_CHANNEL_BINDING   0x0800
0357 
0358 /* This plugin can be used for HTTP authentication */
0359 #define SASL_FEAT_SUPPORTS_HTTP         0x1000
0360 
0361 /* client plug-in features */
0362 #define SASL_FEAT_NEEDSERVERFQDN    0x0001
0363 
0364 /* a C object for a client mechanism
0365  */
0366 typedef struct sasl_client_plug {
0367     /* mechanism name */
0368     const char *mech_name;
0369 
0370     /* best mech additional security layer strength factor */
0371     sasl_ssf_t max_ssf;
0372 
0373     /* best security flags, as defined in sasl_security_properties_t */
0374     unsigned security_flags;
0375 
0376     /* features of plugin */
0377     unsigned features;
0378 
0379     /* required prompt ids, NULL = user/pass only */
0380     const unsigned long *required_prompts;
0381     
0382     /* global state for mechanism */
0383     void *glob_context;
0384     
0385     /* create context for mechanism, using params supplied
0386      *  glob_context   -- from above
0387      *  params         -- params from sasl_client_new
0388      *  conn_context   -- context for one connection
0389      * returns:
0390      *  SASL_OK        -- success
0391      *  SASL_NOMEM     -- not enough memory
0392      *  SASL_WRONGMECH -- mech doesn't support security params
0393      */
0394     int (*mech_new)(void *glob_context,
0395             sasl_client_params_t *cparams,
0396             void **conn_context);
0397     
0398     /* perform one step of exchange.  NULL is passed for serverin on
0399      * first step.
0400      * returns:
0401      *  SASL_OK        -- success
0402      *  SASL_INTERACT  -- user interaction needed to fill in prompts
0403      *  SASL_BADPROT   -- server protocol incorrect/cancelled
0404      *  SASL_BADSERV   -- server failed mutual auth
0405      */
0406     int (*mech_step)(void *conn_context,
0407              sasl_client_params_t *cparams,
0408              const char *serverin,
0409              unsigned serverinlen,
0410              sasl_interact_t **prompt_need,
0411              const char **clientout,
0412              unsigned *clientoutlen,
0413              sasl_out_params_t *oparams);
0414     
0415     /* dispose of connection context from mech_new
0416      */
0417     void (*mech_dispose)(void *conn_context, const sasl_utils_t *utils);
0418     
0419     /* free all global space used by mechanism
0420      *  mech_dispose must be called on all mechanisms first
0421      */
0422     void (*mech_free)(void *glob_context, const sasl_utils_t *utils);
0423      
0424     /* perform precalculations during a network round-trip
0425      *  or idle period.  conn_context may be NULL
0426      *  returns 1 if action taken, 0 if no action taken
0427      */
0428     int (*idle)(void *glob_context,
0429         void *conn_context,
0430         sasl_client_params_t *cparams);
0431 
0432     /* for additions which don't require a version upgrade; set to 0 */
0433     int (*spare_fptr1)(void);
0434     int (*spare_fptr2)(void);
0435 } sasl_client_plug_t;
0436 
0437 #define SASL_CLIENT_PLUG_VERSION         4
0438 
0439 /* plug-in entry point:
0440  *  utils       -- utility callback functions
0441  *  max_version -- highest client plug version supported
0442  * returns:
0443  *  out_version -- client plug version of result
0444  *  pluglist    -- list of mechanism plug-ins
0445  *  plugcount   -- number of mechanism plug-ins
0446  * results:
0447  *  SASL_OK       -- success
0448  *  SASL_NOMEM    -- failure
0449  *  SASL_BADVERS  -- max_version too small
0450  *  SASL_BADPARAM -- bad config string
0451  *  ...
0452  */
0453 typedef int sasl_client_plug_init_t(const sasl_utils_t *utils,
0454                     int max_version,
0455                     int *out_version,
0456                     sasl_client_plug_t **pluglist,
0457                     int *plugcount);
0458 
0459 
0460 /* add a client plug-in
0461  */
0462 LIBSASL_API int sasl_client_add_plugin(const char *plugname,
0463                        sasl_client_plug_init_t *cplugfunc);
0464 
0465 typedef struct client_sasl_mechanism
0466 {
0467     int version;
0468 
0469     char *plugname;
0470     const sasl_client_plug_t *plug;
0471 } client_sasl_mechanism_t;
0472 
0473 typedef void sasl_client_info_callback_t (client_sasl_mechanism_t *m,
0474                       sasl_info_callback_stage_t stage,
0475                       void *rock);
0476 
0477 /* Dump information about available client plugins */
0478 LIBSASL_API int sasl_client_plugin_info (const char *mech_list,
0479     sasl_client_info_callback_t *info_cb,
0480     void *info_cb_rock);
0481 
0482 
0483 /********************
0484  * Server Functions *
0485  ********************/
0486 
0487 /* log message formatting routine */
0488 typedef void sasl_logmsg_p(sasl_conn_t *conn, const char *fmt, ...) __attribute__((format(printf, 2, 3)));
0489 
0490 /*
0491  * input parameters to server SASL plugin
0492  *
0493  * created / destroyed by the glue code
0494  *
0495  */
0496 typedef struct sasl_server_params {
0497     const char *service;    /* NULL = default service for user_exists
0498                    and setpass */
0499     const char *appname;    /* name of calling application */
0500     const char *serverFQDN; /* server default fully qualified domain name
0501                  * (e.g., gethostname) */
0502     const char *user_realm; /* realm for user (NULL = client supplied) */
0503     const char *iplocalport;    /* server IP domain literal & port */
0504     const char *ipremoteport;   /* client IP domain literal & port */
0505 
0506     unsigned servicelen;    /* length of service */
0507     unsigned applen;        /* length of appname */
0508     unsigned slen;      /* length of serverFQDN */
0509     unsigned urlen;     /* length of user_realm */
0510     unsigned iploclen;      /* length of iplocalport */
0511     unsigned ipremlen;      /* length of ipremoteport */
0512 
0513     /* This indicates the level of logging desired.  See SASL_LOG_*
0514      * in sasl.h
0515      *
0516      * Plug-ins can ignore this and just pass their desired level to
0517      * the log callback.  This is primarily used to eliminate logging which
0518      * might be a performance problem (e.g., full protocol trace) and
0519      * to select between SASL_LOG_TRACE and SASL_LOG_PASS alternatives
0520      */
0521     int log_level;
0522 
0523     const sasl_utils_t *utils;  /* SASL API utility routines --
0524                  * for a particular sasl_conn_t,
0525                  * MUST remain valid until mech_free is
0526                  * called */
0527     const sasl_callback_t *callbacks;   /* Callbacks from application */
0528 
0529     /* application's security requirements */
0530     sasl_security_properties_t props;
0531     sasl_ssf_t external_ssf;    /* external SSF active */
0532 
0533     /* Pointer to the function which takes the plaintext passphrase and
0534      *  transitions a user to non-plaintext mechanisms via setpass calls.
0535      *  (NULL = auto transition not enabled/supported)
0536      *
0537      *  If passlen is 0, it defaults to strlen(pass).
0538      *  returns 0 if no entry added, 1 if entry added
0539      */
0540     int (*transition)(sasl_conn_t *conn, const char *pass, unsigned passlen);
0541 
0542     /* Canonicalize a user name from on-wire to internal format
0543      *  added cjn 1999-09-21
0544      *  Must be called once user name acquired if canon_user is non-NULL.
0545      *  conn        connection context
0546      *  user        user name from wire protocol (need not be NUL terminated)
0547      *  ulen        length of user name from wire protocol (0 = strlen(user))
0548      *  flags       for SASL_CU_* flags
0549      *  oparams     the user, authid, ulen, alen, fields are
0550      *              set appropriately after canonicalization/copying and
0551      *              authorization of arguments
0552      *
0553      *  responsible for setting user, ulen, authid, and alen in the oparams
0554      *  structure
0555      *
0556      *  default behavior is to strip leading and trailing whitespace, as
0557      *  well as allocating space for and copying the parameters.
0558      *
0559      * results:
0560      *  SASL_OK       -- success
0561      *  SASL_NOMEM    -- out of memory
0562      *  SASL_BADPARAM -- invalid conn
0563      *  SASL_BADPROT  -- invalid user/authid
0564      */
0565     int (*canon_user)(sasl_conn_t *conn,
0566               const char *user, unsigned ulen,
0567               unsigned flags,
0568               sasl_out_params_t *oparams);
0569     
0570     /* auxiliary property context (see definitions in prop.h)
0571      *  added cjn 2000-01-30
0572      *
0573      * NOTE: these properties are the ones associated with the
0574      * canonicalized "user" (user to login as / authorization id), not
0575      * the "authid" (user whose credentials are used / authentication id)
0576      * Prefix the property name with a "*" if a property associated with
0577      * the "authid" is interesting.
0578      */
0579     struct propctx *propctx;
0580 
0581     /* for additions which don't require a version upgrade; set to 0 */
0582     const void *gss_creds;                  /* GSS credential handle */
0583     const sasl_channel_binding_t *cbinding; /* server channel binding */
0584     const sasl_http_request_t *http_request;/* HTTP Digest request method */
0585     void *spare_ptr4;
0586     int (*spare_fptr1)(void);
0587     int (*spare_fptr2)(void);
0588     int spare_int1;
0589     int spare_int2;
0590     int spare_int3;
0591 
0592     /* flags field as passed to sasl_server_new */
0593     unsigned flags;
0594 
0595     /* set to 0 initially, this allows a plugin with extended parameters
0596      * to work with an older framework by updating version as parameters
0597      * are added.
0598      */
0599     int param_version;
0600 } sasl_server_params_t;
0601 
0602 /* logging levels (more levels may be added later, if necessary):
0603  */
0604 #define SASL_LOG_NONE  0    /* don't log anything */
0605 #define SASL_LOG_ERR   1    /* log unusual errors (default) */
0606 #define SASL_LOG_FAIL  2    /* log all authentication failures */
0607 #define SASL_LOG_WARN  3    /* log non-fatal warnings */
0608 #define SASL_LOG_NOTE  4    /* more verbose than LOG_WARN */
0609 #define SASL_LOG_DEBUG 5    /* more verbose than LOG_NOTE */
0610 #define SASL_LOG_TRACE 6    /* traces of internal protocols */
0611 #define SASL_LOG_PASS  7    /* traces of internal protocols, including
0612                  * passwords */
0613 
0614 /* additional flags for setpass() function below:
0615  */
0616 /*      SASL_SET_CREATE                     create user if pass non-NULL */
0617 /*      SASL_SET_DISABLE                    disable user */
0618 #define SASL_SET_REMOVE  SASL_SET_CREATE /* remove user if pass is NULL */
0619 
0620 /* features for server plug-in
0621  */
0622 #define SASL_FEAT_SERVICE    0x0200 /* service-specific passwords supported */
0623 #define SASL_FEAT_GETSECRET  0x0400 /* sasl_server_{get,put}secret_t callbacks
0624                      * required by plug-in */
0625 
0626 /* a C object for a server mechanism
0627  */
0628 typedef struct sasl_server_plug {
0629     /* mechanism name */
0630     const char *mech_name;
0631 
0632     /* best mech additional security layer strength factor */
0633     sasl_ssf_t max_ssf;
0634 
0635     /* best security flags, as defined in sasl_security_properties_t */
0636     unsigned security_flags;
0637 
0638     /* features of plugin */
0639     unsigned features;
0640     
0641     /* global state for mechanism */
0642     void *glob_context;
0643 
0644     /* create a new mechanism handler
0645      *  glob_context  -- global context
0646      *  sparams       -- server config params
0647      *  challenge     -- server challenge from previous instance or NULL
0648      *  challen       -- length of challenge from previous instance or 0
0649      * out:
0650      *  conn_context  -- connection context
0651      *  errinfo       -- error information
0652      *
0653      * returns:
0654      *  SASL_OK       -- successfully created mech instance
0655      *  SASL_*        -- any other server error code
0656      */
0657     int (*mech_new)(void *glob_context,
0658             sasl_server_params_t *sparams,
0659             const char *challenge,
0660             unsigned challen,
0661             void **conn_context);
0662     
0663     /* perform one step in exchange
0664      *
0665      * returns:
0666      *  SASL_OK       -- success, all done
0667      *  SASL_CONTINUE -- success, one more round trip
0668      *  SASL_*        -- any other server error code
0669      */
0670     int (*mech_step)(void *conn_context,
0671              sasl_server_params_t *sparams,
0672              const char *clientin,
0673              unsigned clientinlen,
0674              const char **serverout,
0675              unsigned *serveroutlen,
0676              sasl_out_params_t *oparams);
0677     
0678     /* dispose of a connection state
0679      */
0680     void (*mech_dispose)(void *conn_context, const sasl_utils_t *utils);
0681     
0682     /* free global state for mechanism
0683      *  mech_dispose must be called on all mechanisms first
0684      */
0685     void (*mech_free)(void *glob_context, const sasl_utils_t *utils);
0686     
0687     /* set a password (optional)
0688      *  glob_context  -- global context
0689      *  sparams       -- service, middleware utilities, etc. props ignored
0690      *  user          -- user name
0691      *  pass          -- password/passphrase (NULL = disable/remove/delete)
0692      *  passlen       -- length of password/passphrase
0693      *  oldpass       -- old password/passphrase (NULL = transition)
0694      *  oldpasslen    -- length of password/passphrase
0695      *  flags         -- see above
0696      *
0697      * returns:
0698      *  SASL_NOCHANGE -- no change was needed
0699      *  SASL_NOUSER   -- no entry for user
0700      *  SASL_NOVERIFY -- no mechanism compatible entry for user
0701      *  SASL_PWLOCK   -- password locked
0702      *  SASL_DIABLED  -- account disabled
0703      *  etc.
0704      */
0705     int (*setpass)(void *glob_context,
0706            sasl_server_params_t *sparams,
0707            const char *user,
0708            const char *pass, unsigned passlen,
0709            const char *oldpass, unsigned oldpasslen,
0710            unsigned flags);
0711 
0712     /* query which mechanisms are available for user
0713      *  glob_context  -- context
0714      *  sparams       -- service, middleware utilities, etc. props ignored
0715      *  user          -- NUL terminated user name
0716      *  maxmech       -- max number of strings in mechlist (0 = no output)
0717      * output:
0718      *  mechlist      -- an array of C string pointers, filled in with
0719      *                   mechanism names available to the user
0720      *
0721      * returns:
0722      *  SASL_OK       -- success
0723      *  SASL_NOMEM    -- not enough memory
0724      *  SASL_FAIL     -- lower level failure
0725      *  SASL_DISABLED -- account disabled
0726      *  SASL_NOUSER   -- user not found
0727      *  SASL_BUFOVER  -- maxmech is too small
0728      *  SASL_NOVERIFY -- user found, but no mechanisms available
0729      */
0730     int (*user_query)(void *glob_context,
0731               sasl_server_params_t *sparams,
0732               const char *user,
0733               int maxmech,
0734               const char **mechlist);
0735      
0736     /* perform precalculations during a network round-trip
0737      *  or idle period.  conn_context may be NULL (optional)
0738      *  returns 1 if action taken, 0 if no action taken
0739      */
0740     int (*idle)(void *glob_context,
0741         void *conn_context,
0742         sasl_server_params_t *sparams);
0743 
0744     /* check if mechanism is available
0745      *  optional--if NULL, mechanism is available based on ENABLE= in config
0746      *
0747      *  If this routine sets conn_context to a non-NULL value, then the call
0748      *  to mech_new will be skipped.  This should not be done unless
0749      *  there's a significant performance benefit, since it can cause
0750      *  additional memory allocation in SASL core code to keep track of
0751      *  contexts potentially for multiple mechanisms.
0752      *
0753      *  This is called by the first call to sasl_listmech() for a
0754      *  given connection context, thus for a given protocol it may
0755      *  never be called.  Note that if mech_avail returns SASL_NOMECH,
0756      *  then that mechanism is considered disabled for the remainder
0757      *  of the session.  If mech_avail returns SASL_NOTDONE, then a
0758      *  future call to mech_avail may still return either SASL_OK
0759      *  or SASL_NOMECH.
0760      *
0761      *  returns SASL_OK on success,
0762      *          SASL_NOTDONE if mech is not available now, but may be later
0763      *                       (e.g. EXTERNAL w/o auth_id)
0764      *          SASL_NOMECH if mech disabled
0765      */
0766     int (*mech_avail)(void *glob_context,
0767               sasl_server_params_t *sparams,
0768               void **conn_context);
0769 
0770     /* for additions which don't require a version upgrade; set to 0 */
0771     int (*spare_fptr2)(void);
0772 } sasl_server_plug_t;
0773 
0774 #define SASL_SERVER_PLUG_VERSION 4
0775 
0776 /* plug-in entry point:
0777  *  utils         -- utility callback functions
0778  *  plugname      -- name of plug-in (may be NULL)
0779  *  max_version   -- highest server plug version supported
0780  * returns:
0781  *  out_version   -- server plug-in version of result
0782  *  pluglist      -- list of mechanism plug-ins
0783  *  plugcount     -- number of mechanism plug-ins
0784  * results:
0785  *  SASL_OK       -- success
0786  *  SASL_NOMEM    -- failure
0787  *  SASL_BADVERS  -- max_version too small
0788  *  SASL_BADPARAM -- bad config string
0789  *  ...
0790  */
0791 typedef int sasl_server_plug_init_t(const sasl_utils_t *utils,
0792                     int max_version,
0793                     int *out_version,
0794                     sasl_server_plug_t **pluglist,
0795                     int *plugcount);
0796 
0797 /* 
0798  * add a server plug-in
0799  */
0800 LIBSASL_API int sasl_server_add_plugin(const char *plugname,
0801                        sasl_server_plug_init_t *splugfunc);
0802 
0803 
0804 typedef struct server_sasl_mechanism
0805 {
0806     int version;
0807     int condition; /* set to SASL_NOUSER if no available users;
0808               set to SASL_CONTINUE if delayed plugin loading */
0809     char *plugname; /* for AUTHSOURCE tracking */
0810     const sasl_server_plug_t *plug;
0811     char *f;       /* where should i load the mechanism from? */
0812 } server_sasl_mechanism_t;
0813 
0814 typedef void sasl_server_info_callback_t (server_sasl_mechanism_t *m,
0815                       sasl_info_callback_stage_t stage,
0816                       void *rock);
0817 
0818 
0819 /* Dump information about available server plugins (separate functions are
0820    used for canon and auxprop plugins) */
0821 LIBSASL_API int sasl_server_plugin_info (const char *mech_list,
0822     sasl_server_info_callback_t *info_cb,
0823     void *info_cb_rock);
0824 
0825 
0826 /*********************************************************
0827  * user canonicalization plug-in -- added cjn 1999-09-29 *
0828  *********************************************************/
0829 
0830 typedef struct sasl_canonuser {
0831     /* optional features of plugin (set to 0) */
0832     int features;
0833 
0834     /* spare integer (set to 0) */
0835     int spare_int1;
0836 
0837     /* global state for plugin */
0838     void *glob_context;
0839 
0840     /* name of plugin */
0841     char *name;
0842 
0843     /* free global state for plugin */
0844     void (*canon_user_free)(void *glob_context, const sasl_utils_t *utils);
0845 
0846     /* canonicalize a username
0847      *  glob_context     -- global context from this structure
0848      *  sparams          -- server params, note user_realm&propctx elements
0849      *  user             -- user to login as (may not be NUL terminated)
0850      *  len              -- length of user name (0 = strlen(user))
0851      *  flags            -- for SASL_CU_* flags
0852      *  out              -- buffer to copy user name
0853      *  out_max          -- max length of user name
0854      *  out_len          -- set to length of user name
0855      *
0856      *  note that the output buffers MAY be the same as the input buffers.
0857      *
0858      * returns
0859      *  SASL_OK         on success
0860      *  SASL_BADPROT    username contains invalid character
0861      */
0862     int (*canon_user_server)(void *glob_context,
0863                  sasl_server_params_t *sparams,
0864                  const char *user, unsigned len,
0865                  unsigned flags,
0866                  char *out,
0867                  unsigned out_umax, unsigned *out_ulen);
0868 
0869     int (*canon_user_client)(void *glob_context,
0870                  sasl_client_params_t *cparams,
0871                  const char *user, unsigned len,
0872                  unsigned flags,
0873                  char *out,
0874                  unsigned out_max, unsigned *out_len);
0875 
0876     /* for additions which don't require a version upgrade; set to 0 */
0877     int (*spare_fptr1)(void);
0878     int (*spare_fptr2)(void);
0879     int (*spare_fptr3)(void);
0880 } sasl_canonuser_plug_t;
0881 
0882 #define SASL_CANONUSER_PLUG_VERSION 5
0883 
0884 /* default name for canonuser plug-in entry point is "sasl_canonuser_init"
0885  *  similar to sasl_server_plug_init model, except only returns one
0886  *  sasl_canonuser_plug_t structure;
0887  */
0888 typedef int sasl_canonuser_init_t(const sasl_utils_t *utils,
0889                   int max_version,
0890                   int *out_version,
0891                   sasl_canonuser_plug_t **plug,
0892                   const char *plugname);
0893 
0894 /* add a canonuser plugin
0895  */
0896 LIBSASL_API int sasl_canonuser_add_plugin(const char *plugname,
0897                   sasl_canonuser_init_t *canonuserfunc);
0898 
0899 /******************************************************
0900  * auxiliary property plug-in -- added cjn 1999-09-29 *
0901  ******************************************************/
0902 
0903 typedef struct sasl_auxprop_plug {
0904     /* optional features of plugin (none defined yet, set to 0) */
0905     int features;
0906 
0907     /* spare integer, must be set to 0 */
0908     int spare_int1;
0909 
0910     /* global state for plugin */
0911     void *glob_context;
0912 
0913     /* free global state for plugin (OPTIONAL) */
0914     void (*auxprop_free)(void *glob_context, const sasl_utils_t *utils);
0915 
0916     /* fill in fields of an auxiliary property context
0917      *  last element in array has id of SASL_AUX_END
0918      *  elements with non-0 len should be ignored.
0919      */
0920     int (*auxprop_lookup)(void *glob_context,
0921                sasl_server_params_t *sparams,
0922                unsigned flags,
0923                const char *user, unsigned ulen);
0924 
0925     /* name of the auxprop plugin */
0926     char *name;
0927 
0928     /* store the fields/values of an auxiliary property context (OPTIONAL)
0929      *
0930      * if ctx is NULL, just check if storing properties is enabled
0931      *
0932      * returns
0933      *  SASL_OK         on success
0934      *  SASL_FAIL       on failure
0935      */
0936     int (*auxprop_store)(void *glob_context,
0937              sasl_server_params_t *sparams,
0938              struct propctx *ctx,
0939              const char *user, unsigned ulen);
0940 } sasl_auxprop_plug_t;
0941 
0942 /* auxprop lookup flags */
0943 #define SASL_AUXPROP_OVERRIDE 0x01 /* if clear, ignore auxiliary properties
0944                     * with non-zero len field.  If set,
0945                     * override value of those properties */
0946 #define SASL_AUXPROP_AUTHZID  0x02 /* if clear, we are looking up the
0947                     * authid flags (prefixed with *), otherwise
0948                     * we are looking up the authzid flags
0949                     * (no prefix) */
0950 
0951 /* NOTE: Keep in sync with SASL_CU_<XXX> flags */
0952 #define SASL_AUXPROP_VERIFY_AGAINST_HASH 0x10
0953 
0954 
0955 #define SASL_AUXPROP_PLUG_VERSION 8
0956 
0957 /* default name for auxprop plug-in entry point is "sasl_auxprop_init"
0958  *  similar to sasl_server_plug_init model, except only returns one
0959  *  sasl_auxprop_plug_t structure;
0960  */
0961 typedef int sasl_auxprop_init_t(const sasl_utils_t *utils,
0962                 int max_version,
0963                 int *out_version,
0964                 sasl_auxprop_plug_t **plug,
0965                 const char *plugname);
0966 
0967 /* add an auxiliary property plug-in
0968  */
0969 LIBSASL_API int sasl_auxprop_add_plugin(const char *plugname,
0970                     sasl_auxprop_init_t *auxpropfunc);
0971 
0972 typedef void auxprop_info_callback_t (sasl_auxprop_plug_t *m,
0973                           sasl_info_callback_stage_t stage,
0974                       void *rock);
0975 
0976 /* Dump information about available auxprop plugins (separate functions are
0977    used for canon and server authentication plugins) */
0978 LIBSASL_API int auxprop_plugin_info (const char *mech_list,
0979     auxprop_info_callback_t *info_cb,
0980     void *info_cb_rock);
0981 
0982 #ifdef __cplusplus
0983 }
0984 #endif
0985 
0986 #endif /* SASLPLUG_H */