1/* saslplug.h --  API for SASL plug-ins
2 */
3
4#ifndef SASLPLUG_H
5#define SASLPLUG_H 1
6
7#ifndef MD5GLOBAL_H
8#include "md5global.h"
9#endif
10#ifndef MD5_H
11#include "md5.h"
12#endif
13#ifndef HMAC_MD5_H
14#include "hmac-md5.h"
15#endif
16#ifndef PROP_H
17#include "prop.h"
18#endif
19
20#ifdef __cplusplus
21extern "C" {
22#endif
23
24/* callback to lookup a sasl_callback_t for a connection
25 * input:
26 *  conn        -- the connection to lookup a callback for
27 *  callbacknum -- the number of the callback
28 * output:
29 *  pproc       -- pointer to the callback function (set to NULL on failure)
30 *  pcontext    -- pointer to the callback context (set to NULL on failure)
31 * returns:
32 *  SASL_OK -- no error
33 *  SASL_FAIL -- unable to find a callback of the requested type
34 *  SASL_INTERACT -- caller must use interaction to get data
35 */
36typedef int (*sasl_callback_ft)(); // APPLE: remove void
37typedef int sasl_getcallback_t(sasl_conn_t *conn,
38			       unsigned long callbackid,
39			       sasl_callback_ft * pproc,
40			       void **pcontext);
41
42/* The sasl_utils structure will remain backwards compatible unless
43 * the SASL_*_PLUG_VERSION is changed incompatibly
44 * higher SASL_UTILS_VERSION numbers indicate more functions are available
45 */
46#define SASL_UTILS_VERSION 4
47
48/* utility function set for plug-ins
49 */
50typedef struct sasl_utils {
51    int version;
52
53    /* contexts */
54    sasl_conn_t *conn;
55    sasl_rand_t *rpool;
56    void *getopt_context;
57
58    /* option function */
59    sasl_getopt_t *getopt;
60
61    /* allocation functions: */
62    sasl_malloc_t *malloc;
63    sasl_calloc_t *calloc;
64    sasl_realloc_t *realloc;
65    sasl_free_t *free;
66
67    /* mutex functions: */
68    sasl_mutex_alloc_t *mutex_alloc;
69    sasl_mutex_lock_t *mutex_lock;
70    sasl_mutex_unlock_t *mutex_unlock;
71    sasl_mutex_free_t *mutex_free;
72
73    /* MD5 hash and HMAC functions */
74    void (*MD5Init)(MD5_CTX *);
75    void (*MD5Update)(MD5_CTX *, const unsigned char *text, unsigned int len);
76    void (*MD5Final)(unsigned char [16], MD5_CTX *);
77    void (*hmac_md5)(const unsigned char *text, int text_len,
78		     const unsigned char *key, int key_len,
79		     unsigned char [16]);
80    void (*hmac_md5_init)(HMAC_MD5_CTX *, const unsigned char *key, int len);
81    /* hmac_md5_update() is just a call to MD5Update on inner context */
82    void (*hmac_md5_final)(unsigned char [16], HMAC_MD5_CTX *);
83    void (*hmac_md5_precalc)(HMAC_MD5_STATE *,
84			     const unsigned char *key, int len);
85    void (*hmac_md5_import)(HMAC_MD5_CTX *, HMAC_MD5_STATE *);
86
87    /* mechanism utility functions (same as above): */
88    int (*mkchal)(sasl_conn_t *conn, char *buf, unsigned maxlen,
89		  unsigned hostflag);
90    int (*utf8verify)(const char *str, unsigned len);
91    void (*rand)(sasl_rand_t *rpool, char *buf, unsigned len);
92    void (*churn)(sasl_rand_t *rpool, const char *data, unsigned len);
93
94    /* This allows recursive calls to the sasl_checkpass() routine from
95     * within a SASL plug-in.  This MUST NOT be used in the PLAIN mechanism
96     * as sasl_checkpass MAY be a front-end for the PLAIN mechanism.
97     * This is intended for use by the non-standard LOGIN mechanism and
98     * potentially by a future mechanism which uses public-key technology to
99     * set up a lightweight encryption layer just for sending a password.
100     */
101    int (*checkpass)(sasl_conn_t *conn,
102		     const char *user, unsigned userlen,
103		     const char *pass, unsigned passlen);
104
105    /* Access to base64 encode/decode routines */
106    int (*decode64)(const char *in, unsigned inlen,
107		    char *out, unsigned outmax, unsigned *outlen);
108    int (*encode64)(const char *in, unsigned inlen,
109		    char *out, unsigned outmax, unsigned *outlen);
110
111    /* erase a buffer */
112    void (*erasebuffer)(char *buf, unsigned len);
113
114    /* callback to sasl_getprop() and sasl_setprop() */
115    int (*getprop)(sasl_conn_t *conn, int propnum, const void **pvalue);
116    int (*setprop)(sasl_conn_t *conn, int propnum, const void *value);
117
118    /* callback function */
119    sasl_getcallback_t *getcallback;
120
121    /* format a message and then pass it to the SASL_CB_LOG callback
122     *
123     * use syslog()-style formatting (printf with %m as a human readable text
124     * (strerror()) for the error specified as the parameter).
125     * The implementation may use a fixed size buffer not smaller
126     * than 512 octets if it securely truncates the message.
127     *
128     * level is a SASL_LOG_* level (see sasl.h)
129     */
130    void (*log)(sasl_conn_t *conn, int level, const char *fmt, ...);
131
132    /* callback to sasl_seterror() */
133    void (*seterror)(sasl_conn_t *conn, unsigned flags, const char *fmt, ...);
134
135    /* spare function pointer */
136    int *(*spare_fptr)(void);
137
138    /* auxiliary property utilities */
139    struct propctx *(*prop_new)(unsigned estimate);
140    int (*prop_dup)(struct propctx *src_ctx, struct propctx **dst_ctx);
141    int (*prop_request)(struct propctx *ctx, const char **names);
142    const struct propval *(*prop_get)(struct propctx *ctx);
143    int (*prop_getnames)(struct propctx *ctx, const char **names,
144			 struct propval *vals);
145    void (*prop_clear)(struct propctx *ctx, int requests);
146    void (*prop_dispose)(struct propctx **ctx);
147    int (*prop_format)(struct propctx *ctx, const char *sep, int seplen,
148		       char *outbuf, unsigned outmax, unsigned *outlen);
149    int (*prop_set)(struct propctx *ctx, const char *name,
150		    const char *value, int vallen);
151    int (*prop_setvals)(struct propctx *ctx, const char *name,
152			const char **values);
153    void (*prop_erase)(struct propctx *ctx, const char *name);
154    int (*auxprop_store)(sasl_conn_t *conn,
155			 struct propctx *ctx, const char *user);
156
157    /* for additions which don't require a version upgrade; set to 0 */
158    int (*spare_fptr1)(void);
159    int (*spare_fptr2)(void);
160} sasl_utils_t;
161
162/*
163 * output parameters from SASL API
164 *
165 * created / destroyed by the glue code, though probably filled in
166 * by a combination of the plugin, the glue code, and the canon_user callback.
167 *
168 */
169typedef struct sasl_out_params {
170    unsigned doneflag;		/* exchange complete */
171
172    const char *user;		/* canonicalized user name */
173    const char *authid;		/* canonicalized authentication id */
174
175    unsigned ulen;		/* length of canonicalized user name */
176    unsigned alen;		/* length of canonicalized authid */
177
178    /* security layer information */
179    unsigned maxoutbuf;         /* Maximum buffer size, which will
180                                   produce buffer no bigger than the
181                                   negotiated SASL maximum buffer size */
182    sasl_ssf_t mech_ssf;   /* Should be set non-zero if negotiation of a
183	 		    * security layer was *attempted*, even if
184			    * the negotiation failed */
185    void *encode_context;
186    int (*encode)(void *context, const struct iovec *invec, unsigned numiov,
187		  const char **output, unsigned *outputlen);
188    void *decode_context;
189    int (*decode)(void *context, const char *input, unsigned inputlen,
190		  const char **output, unsigned *outputlen);
191
192    /* Pointer to delegated (client's) credentials, if supported by
193       the SASL mechanism */
194    void *client_creds;
195
196    /* for additions which don't require a version upgrade; set to 0 */
197    /* APPLE: unions for compatibility with 2.1.22 and 2.1.26 */
198    union {
199        void *spare_ptr2;
200        const void *gss_peer_name;
201    };
202    union {
203        void *spare_ptr3;
204        const void *gss_local_name;
205    };
206    union {
207        void *spare_ptr4;
208        const char *cbindingname;   /* channel binding name from packet */
209    };
210    int (*spare_fptr1)();
211    int (*spare_fptr2)();
212    union {
213        int spare_int1;
214        unsigned int cbindingdisp;  /* channel binding disposition from client */
215    };
216    int spare_int2;
217    int spare_int3;
218    int spare_int4;
219
220    /* set to 0 initially, this allows a plugin with extended parameters
221     * to work with an older framework by updating version as parameters
222     * are added.
223     */
224    int param_version;
225} sasl_out_params_t;
226
227
228
229/* Used by both client and server side plugins */
230typedef enum  {
231    SASL_INFO_LIST_START = 0,
232    SASL_INFO_LIST_MECH,
233    SASL_INFO_LIST_END
234} sasl_info_callback_stage_t;
235
236/******************************
237 * Channel binding macros     **
238 ******************************/
239
240typedef enum {
241    SASL_CB_DISP_NONE = 0,          /* client did not support CB */
242    SASL_CB_DISP_WANT,              /* client supports CB, thinks server does not */
243    SASL_CB_DISP_USED               /* client supports and used CB */
244} sasl_cbinding_disp_t;
245
246/* TRUE if channel binding is non-NULL */
247#define SASL_CB_PRESENT(params)     ((params)->cbinding != NULL)
248/* TRUE if channel binding is marked critical */
249#define SASL_CB_CRITICAL(params)    (SASL_CB_PRESENT(params) && \
250				     (params)->cbinding->critical)
251
252/******************************
253 * Client Mechanism Functions *
254 ******************************/
255
256/*
257 * input parameters to client SASL plugin
258 *
259 * created / destroyed by the glue code
260 *
261 */
262typedef struct sasl_client_params {
263    const char *service;	/* service name */
264    const char *serverFQDN;	/* server fully qualified domain name */
265    const char *clientFQDN;	/* client's fully qualified domain name */
266    const sasl_utils_t *utils;	/* SASL API utility routines --
267				 * for a particular sasl_conn_t,
268				 * MUST remain valid until mech_free is
269				 * called */
270    const sasl_callback_t *prompt_supp; /* client callback list */
271    const char *iplocalport;	/* server IP domain literal & port */
272    const char *ipremoteport;	/* client IP domain literal & port */
273
274    unsigned servicelen;	/* length of service */
275    unsigned slen;		/* length of serverFQDN */
276    unsigned clen;		/* length of clientFQDN */
277    unsigned iploclen;		/* length of iplocalport */
278    unsigned ipremlen;		/* length of ipremoteport */
279
280    /* application's security requirements & info */
281    sasl_security_properties_t props;
282    sasl_ssf_t external_ssf;	/* external SSF active */
283
284    /* for additions which don't require a version upgrade; set to 0 */
285    /* APPLE: unions for compatibility with 2.1.22 and 2.1.26 */
286    union {
287        void *spare_ptr1;
288        const void *gss_creds;                  /* GSS credential handle */
289    };
290    union {
291        void *spare_ptr2;
292        const sasl_channel_binding_t *cbinding; /* client channel binding */
293    };
294    union {
295        void *spare_ptr3;
296        const sasl_http_request_t *http_request;/* HTTP Digest request method */
297    };
298    void *spare_ptr4;
299
300    /* Canonicalize a user name from on-wire to internal format
301     *  added rjs3 2001-05-23
302     *  Must be called once user name aquired if canon_user is non-NULL.
303     *  conn        connection context
304     *  in          user name from wire protocol (need not be NUL terminated)
305     *  len         length of user name from wire protocol (0 = strlen(user))
306     *  flags       for SASL_CU_* flags
307     *  oparams     the user, authid, ulen, alen, fields are
308     *              set appropriately after canonicalization/copying and
309     *              authorization of arguments
310     *
311     *  responsible for setting user, ulen, authid, and alen in the oparams
312     *  structure
313     *
314     *  default behavior is to strip leading and trailing whitespace, as
315     *  well as allocating space for and copying the parameters.
316     *
317     * results:
318     *  SASL_OK       -- success
319     *  SASL_NOMEM    -- out of memory
320     *  SASL_BADPARAM -- invalid conn
321     *  SASL_BADPROT  -- invalid user/authid
322     */
323    int (*canon_user)(sasl_conn_t *conn,
324                    const char *in, unsigned len,
325                    unsigned flags,
326                    sasl_out_params_t *oparams);
327
328    int (*spare_fptr1)(void);
329
330    union {
331        int spare_int1;
332        unsigned int cbindingdisp;
333    };
334    int spare_int2;
335    int spare_int3;
336
337    /* flags field as passed to sasl_client_new */
338    unsigned flags;
339
340    /* set to 0 initially, this allows a plugin with extended parameters
341     * to work with an older framework by updating version as parameters
342     * are added.
343     */
344    int param_version;
345} sasl_client_params_t;
346
347/* features shared between client and server */
348/* These allow the glue code to handle client-first and server-last issues */
349
350/* This indicates that the mechanism prefers to do client-send-first
351 * if the protocol allows it. */
352#define SASL_FEAT_WANT_CLIENT_FIRST 0x0002
353
354/* This feature is deprecated.  Instead, plugins should set *serverout to
355 * non-NULL and return SASL_OK intelligently to allow flexible use of
356 * server-last semantics
357#define SASL_FEAT_WANT_SERVER_LAST	0x0004
358*/
359
360/* This feature is deprecated.  Instead, plugins should correctly set
361 * SASL_FEAT_SERVER_FIRST as needed
362#define SASL_FEAT_INTERNAL_CLIENT_FIRST	0x0008
363*/
364
365/* This indicates that the plugin is server-first only.
366 * Not defining either of SASL_FEAT_SERVER_FIRST or
367 * SASL_FEAT_WANT_CLIENT_FIRST indicates that the mechanism
368 * will handle the client-first situation internally.
369 */
370#define SASL_FEAT_SERVER_FIRST 0x0010
371
372/* This plugin allows proxying */
373#define SASL_FEAT_ALLOWS_PROXY 0x0020
374
375/* server plugin don't use cleartext userPassword attribute */
376#define SASL_FEAT_DONTUSE_USERPASSWD 	0x0080
377
378/* Underlying mechanism uses GSS framing */
379#define SASL_FEAT_GSS_FRAMING	 	0x0100
380
381/* Underlying mechanism supports channel binding */
382#define SASL_FEAT_CHANNEL_BINDING	0x0800
383
384/* This plugin can be used for HTTP authentication */
385#define SASL_FEAT_SUPPORTS_HTTP	    	0x1000
386
387/* client plug-in features */
388#define SASL_FEAT_NEEDSERVERFQDN 0x0001
389
390/* a C object for a client mechanism
391 */
392typedef struct sasl_client_plug {
393    /* mechanism name */
394    const char *mech_name;
395
396    /* best mech additional security layer strength factor */
397    sasl_ssf_t max_ssf;
398
399    /* best security flags, as defined in sasl_security_properties_t */
400    unsigned security_flags;
401
402    /* features of plugin */
403    unsigned features;
404
405    /* required prompt ids, NULL = user/pass only */
406    const unsigned long *required_prompts;
407
408    /* global state for mechanism */
409    void *glob_context;
410
411    /* create context for mechanism, using params supplied
412     *  glob_context   -- from above
413     *  params         -- params from sasl_client_new
414     *  conn_context   -- context for one connection
415     * returns:
416     *  SASL_OK        -- success
417     *  SASL_NOMEM     -- not enough memory
418     *  SASL_WRONGMECH -- mech doesn't support security params
419     */
420    int (*mech_new)(void *glob_context,
421		    sasl_client_params_t *cparams,
422		    void **conn_context);
423
424    /* perform one step of exchange.  NULL is passed for serverin on
425     * first step.
426     * returns:
427     *  SASL_OK        -- success
428     *  SASL_INTERACT  -- user interaction needed to fill in prompts
429     *  SASL_BADPROT   -- server protocol incorrect/cancelled
430     *  SASL_BADSERV   -- server failed mutual auth
431     */
432    int (*mech_step)(void *conn_context,
433		     sasl_client_params_t *cparams,
434		     const char *serverin,
435		     unsigned serverinlen,
436		     sasl_interact_t **prompt_need,
437		     const char **clientout,
438		     unsigned *clientoutlen,
439		     sasl_out_params_t *oparams);
440
441    /* dispose of connection context from mech_new
442     */
443    void (*mech_dispose)(void *conn_context, const sasl_utils_t *utils);
444
445    /* free all global space used by mechanism
446     *  mech_dispose must be called on all mechanisms first
447     */
448    void (*mech_free)(void *glob_context, const sasl_utils_t *utils);
449
450    /* perform precalculations during a network round-trip
451     *  or idle period.  conn_context may be NULL
452     *  returns 1 if action taken, 0 if no action taken
453     */
454    int (*idle)(void *glob_context,
455		void *conn_context,
456		sasl_client_params_t *cparams);
457
458    /* for additions which don't require a version upgrade; set to 0 */
459    int (*spare_fptr1)(void);
460    int (*spare_fptr2)(void);
461} sasl_client_plug_t;
462
463#define SASL_CLIENT_PLUG_VERSION         4
464
465/* plug-in entry point:
466 *  utils       -- utility callback functions
467 *  max_version -- highest client plug version supported
468 * returns:
469 *  out_version -- client plug version of result
470 *  pluglist    -- list of mechanism plug-ins
471 *  plugcount   -- number of mechanism plug-ins
472 * results:
473 *  SASL_OK       -- success
474 *  SASL_NOMEM    -- failure
475 *  SASL_BADVERS  -- max_version too small
476 *  SASL_BADPARAM -- bad config string
477 *  ...
478 */
479typedef int sasl_client_plug_init_t(const sasl_utils_t *utils,
480				    int max_version,
481				    int *out_version,
482				    sasl_client_plug_t **pluglist,
483				    int *plugcount);
484
485
486/* add a client plug-in
487 */
488LIBSASL_API int sasl_client_add_plugin(const char *plugname,
489				       sasl_client_plug_init_t *cplugfunc);
490
491typedef struct client_sasl_mechanism
492{
493    int version;
494
495    char *plugname;
496    const sasl_client_plug_t *plug;
497} client_sasl_mechanism_t;
498
499typedef void sasl_client_info_callback_t (client_sasl_mechanism_t *m,
500					  sasl_info_callback_stage_t stage,
501					  void *rock);
502
503/* Dump information about available client plugins */
504LIBSASL_API int sasl_client_plugin_info (const char *mech_list,
505	sasl_client_info_callback_t *info_cb,
506	void *info_cb_rock);
507
508
509/********************
510 * Server Functions *
511 ********************/
512
513/* log message formatting routine */
514typedef void sasl_logmsg_p(sasl_conn_t *conn, const char *fmt, ...);
515
516/*
517 * input parameters to server SASL plugin
518 *
519 * created / destroyed by the glue code
520 *
521 */
522typedef struct sasl_server_params {
523    const char *service;	/* NULL = default service for user_exists
524				   and setpass */
525    const char *appname;	/* name of calling application */
526    const char *serverFQDN;	/* server default fully qualified domain name
527				 * (e.g., gethostname) */
528    const char *user_realm;	/* realm for user (NULL = client supplied) */
529    const char *iplocalport;	/* server IP domain literal & port */
530    const char *ipremoteport;	/* client IP domain literal & port */
531
532    unsigned servicelen;	/* length of service */
533    unsigned applen;		/* length of appname */
534    unsigned slen;		/* length of serverFQDN */
535    unsigned urlen;		/* length of user_realm */
536    unsigned iploclen;		/* length of iplocalport */
537    unsigned ipremlen;		/* length of ipremoteport */
538
539    /* This indicates the level of logging desired.  See SASL_LOG_*
540     * in sasl.h
541     *
542     * Plug-ins can ignore this and just pass their desired level to
543     * the log callback.  This is primarily used to eliminate logging which
544     * might be a performance problem (e.g., full protocol trace) and
545     * to select between SASL_LOG_TRACE and SASL_LOG_PASS alternatives
546     */
547    int log_level;
548
549    const sasl_utils_t *utils;	/* SASL API utility routines --
550				 * for a particular sasl_conn_t,
551				 * MUST remain valid until mech_free is
552				 * called */
553    const sasl_callback_t *callbacks;	/* Callbacks from application */
554
555    /* application's security requirements */
556    sasl_security_properties_t props;
557    sasl_ssf_t external_ssf;	/* external SSF active */
558
559    /* Pointer to the function which takes the plaintext passphrase and
560     *  transitions a user to non-plaintext mechanisms via setpass calls.
561     *  (NULL = auto transition not enabled/supported)
562     *
563     *  If passlen is 0, it defaults to strlen(pass).
564     *  returns 0 if no entry added, 1 if entry added
565     */
566    int (*transition)(sasl_conn_t *conn, const char *pass, unsigned passlen);
567
568    /* Canonicalize a user name from on-wire to internal format
569     *  added cjn 1999-09-21
570     *  Must be called once user name acquired if canon_user is non-NULL.
571     *  conn        connection context
572     *  user        user name from wire protocol (need not be NUL terminated)
573     *  ulen        length of user name from wire protocol (0 = strlen(user))
574     *  flags       for SASL_CU_* flags
575     *  oparams     the user, authid, ulen, alen, fields are
576     *              set appropriately after canonicalization/copying and
577     *              authorization of arguments
578     *
579     *  responsible for setting user, ulen, authid, and alen in the oparams
580     *  structure
581     *
582     *  default behavior is to strip leading and trailing whitespace, as
583     *  well as allocating space for and copying the parameters.
584     *
585     * results:
586     *  SASL_OK       -- success
587     *  SASL_NOMEM    -- out of memory
588     *  SASL_BADPARAM -- invalid conn
589     *  SASL_BADPROT  -- invalid user/authid
590     */
591    int (*canon_user)(sasl_conn_t *conn,
592		      const char *user, unsigned ulen,
593		      unsigned flags,
594		      sasl_out_params_t *oparams);
595
596    /* auxiliary property context (see definitions in prop.h)
597     *  added cjn 2000-01-30
598     *
599     * NOTE: these properties are the ones associated with the
600     * canonicalized "user" (user to login as / authorization id), not
601     * the "authid" (user whose credentials are used / authentication id)
602     * Prefix the property name with a "*" if a property associated with
603     * the "authid" is interesting.
604     */
605    struct propctx *propctx;
606
607    /* for additions which don't require a version upgrade; set to 0 */
608    /* APPLE: unions for compatibility with 2.1.22 and 2.1.26 */
609    union {
610        void *spare_ptr1;
611        const void *gss_creds;                  /* GSS credential handle */
612    };
613    union {
614        void *spare_ptr2;
615        const sasl_channel_binding_t *cbinding; /* server channel binding */;
616    };
617    union {
618        void *spare_ptr3;
619        const sasl_http_request_t *http_request;/* HTTP Digest request method */
620    };
621    void *spare_ptr4;
622    int (*spare_fptr1)(void);
623    int (*spare_fptr2)(void);
624    int spare_int1;
625    int spare_int2;
626    int spare_int3;
627
628    /* flags field as passed to sasl_server_new */
629    unsigned flags;
630
631    /* set to 0 initially, this allows a plugin with extended parameters
632     * to work with an older framework by updating version as parameters
633     * are added.
634     */
635    int param_version;
636} sasl_server_params_t;
637
638/* logging levels (more levels may be added later, if necessary):
639 */
640#define SASL_LOG_NONE  0	/* don't log anything */
641#define SASL_LOG_ERR   1	/* log unusual errors (default) */
642#define SASL_LOG_FAIL  2	/* log all authentication failures */
643#define SASL_LOG_WARN  3	/* log non-fatal warnings */
644#define SASL_LOG_NOTE  4	/* more verbose than LOG_WARN */
645#define SASL_LOG_DEBUG 5	/* more verbose than LOG_NOTE */
646#define SASL_LOG_TRACE 6	/* traces of internal protocols */
647#define SASL_LOG_PASS  7	/* traces of internal protocols, including
648				 * passwords */
649
650/* additional flags for setpass() function below:
651 */
652/*      SASL_SET_CREATE                     create user if pass non-NULL */
653/*      SASL_SET_DISABLE                    disable user */
654#define SASL_SET_REMOVE  SASL_SET_CREATE /* remove user if pass is NULL */
655
656/* features for server plug-in
657 */
658#define SASL_FEAT_SERVICE    0x0200 /* service-specific passwords supported */
659#define SASL_FEAT_GETSECRET  0x0400 /* sasl_server_{get,put}secret_t callbacks
660				     * required by plug-in */
661
662/* a C object for a server mechanism
663 */
664typedef struct sasl_server_plug {
665    /* mechanism name */
666    const char *mech_name;
667
668    /* best mech additional security layer strength factor */
669    sasl_ssf_t max_ssf;
670
671    /* best security flags, as defined in sasl_security_properties_t */
672    unsigned security_flags;
673
674    /* features of plugin */
675    unsigned features;
676
677    /* global state for mechanism */
678    void *glob_context;
679
680    /* create a new mechanism handler
681     *  glob_context  -- global context
682     *  sparams       -- server config params
683     *  challenge     -- server challenge from previous instance or NULL
684     *  challen       -- length of challenge from previous instance or 0
685     * out:
686     *  conn_context  -- connection context
687     *  errinfo       -- error information
688     *
689     * returns:
690     *  SASL_OK       -- successfully created mech instance
691     *  SASL_*        -- any other server error code
692     */
693    int (*mech_new)(void *glob_context,
694		    sasl_server_params_t *sparams,
695		    const char *challenge,
696		    unsigned challen,
697		    void **conn_context);
698
699    /* perform one step in exchange
700     *
701     * returns:
702     *  SASL_OK       -- success, all done
703     *  SASL_CONTINUE -- success, one more round trip
704     *  SASL_*        -- any other server error code
705     */
706    int (*mech_step)(void *conn_context,
707		     sasl_server_params_t *sparams,
708		     const char *clientin,
709		     unsigned clientinlen,
710		     const char **serverout,
711		     unsigned *serveroutlen,
712		     sasl_out_params_t *oparams);
713
714    /* dispose of a connection state
715     */
716    void (*mech_dispose)(void *conn_context, const sasl_utils_t *utils);
717
718    /* free global state for mechanism
719     *  mech_dispose must be called on all mechanisms first
720     */
721    void (*mech_free)(void *glob_context, const sasl_utils_t *utils);
722
723    /* set a password (optional)
724     *  glob_context  -- global context
725     *  sparams       -- service, middleware utilities, etc. props ignored
726     *  user          -- user name
727     *  pass          -- password/passphrase (NULL = disable/remove/delete)
728     *  passlen       -- length of password/passphrase
729     *  oldpass       -- old password/passphrase (NULL = transition)
730     *  oldpasslen    -- length of password/passphrase
731     *  flags         -- see above
732     *
733     * returns:
734     *  SASL_NOCHANGE -- no change was needed
735     *  SASL_NOUSER   -- no entry for user
736     *  SASL_NOVERIFY -- no mechanism compatible entry for user
737     *  SASL_PWLOCK   -- password locked
738     *  SASL_DIABLED  -- account disabled
739     *  etc.
740     */
741    int (*setpass)(void *glob_context,
742		   sasl_server_params_t *sparams,
743		   const char *user,
744		   const char *pass, unsigned passlen,
745		   const char *oldpass, unsigned oldpasslen,
746		   unsigned flags);
747
748    /* query which mechanisms are available for user
749     *  glob_context  -- context
750     *  sparams       -- service, middleware utilities, etc. props ignored
751     *  user          -- NUL terminated user name
752     *  maxmech       -- max number of strings in mechlist (0 = no output)
753     * output:
754     *  mechlist      -- an array of C string pointers, filled in with
755     *                   mechanism names available to the user
756     *
757     * returns:
758     *  SASL_OK       -- success
759     *  SASL_NOMEM    -- not enough memory
760     *  SASL_FAIL     -- lower level failure
761     *  SASL_DISABLED -- account disabled
762     *  SASL_NOUSER   -- user not found
763     *  SASL_BUFOVER  -- maxmech is too small
764     *  SASL_NOVERIFY -- user found, but no mechanisms available
765     */
766    int (*user_query)(void *glob_context,
767		      sasl_server_params_t *sparams,
768		      const char *user,
769		      int maxmech,
770		      const char **mechlist);
771
772    /* perform precalculations during a network round-trip
773     *  or idle period.  conn_context may be NULL (optional)
774     *  returns 1 if action taken, 0 if no action taken
775     */
776    int (*idle)(void *glob_context,
777		void *conn_context,
778		sasl_server_params_t *sparams);
779
780    /* check if mechanism is available
781     *  optional--if NULL, mechanism is available based on ENABLE= in config
782     *
783     *  If this routine sets conn_context to a non-NULL value, then the call
784     *  to mech_new will be skipped.  This should not be done unless
785     *  there's a significant performance benefit, since it can cause
786     *  additional memory allocation in SASL core code to keep track of
787     *  contexts potentially for multiple mechanisms.
788     *
789     *  This is called by the first call to sasl_listmech() for a
790     *  given connection context, thus for a given protocol it may
791     *  never be called.  Note that if mech_avail returns SASL_NOMECH,
792     *  then that mechanism is considered disabled for the remainder
793     *  of the session.  If mech_avail returns SASL_NOTDONE, then a
794     *  future call to mech_avail may still return either SASL_OK
795     *  or SASL_NOMECH.
796     *
797     *  returns SASL_OK on success,
798     *          SASL_NOTDONE if mech is not available now, but may be later
799     *                       (e.g. EXTERNAL w/o auth_id)
800     *          SASL_NOMECH if mech disabled
801     */
802    int (*mech_avail)(void *glob_context,
803		      sasl_server_params_t *sparams,
804		      void **conn_context);
805
806    /* for additions which don't require a version upgrade; set to 0 */
807    int (*spare_fptr2)(void);
808} sasl_server_plug_t;
809
810#define SASL_SERVER_PLUG_VERSION 4
811
812/* plug-in entry point:
813 *  utils         -- utility callback functions
814 *  plugname      -- name of plug-in (may be NULL)
815 *  max_version   -- highest server plug version supported
816 * returns:
817 *  out_version   -- server plug-in version of result
818 *  pluglist      -- list of mechanism plug-ins
819 *  plugcount     -- number of mechanism plug-ins
820 * results:
821 *  SASL_OK       -- success
822 *  SASL_NOMEM    -- failure
823 *  SASL_BADVERS  -- max_version too small
824 *  SASL_BADPARAM -- bad config string
825 *  ...
826 */
827typedef int sasl_server_plug_init_t(const sasl_utils_t *utils,
828				    int max_version,
829				    int *out_version,
830				    sasl_server_plug_t **pluglist,
831				    int *plugcount);
832
833/*
834 * add a server plug-in
835 */
836LIBSASL_API int sasl_server_add_plugin(const char *plugname,
837				       sasl_server_plug_init_t *splugfunc);
838
839
840typedef struct server_sasl_mechanism
841{
842    int version;
843    int condition; /* set to SASL_NOUSER if no available users;
844		      set to SASL_CONTINUE if delayed plugin loading */
845    char *plugname; /* for AUTHSOURCE tracking */
846    const sasl_server_plug_t *plug;
847    char *f;       /* where should i load the mechanism from? */
848} server_sasl_mechanism_t;
849
850typedef void sasl_server_info_callback_t (server_sasl_mechanism_t *m,
851					  sasl_info_callback_stage_t stage,
852					  void *rock);
853
854
855/* Dump information about available server plugins (separate functions are
856   used for canon and auxprop plugins) */
857LIBSASL_API int sasl_server_plugin_info (const char *mech_list,
858	sasl_server_info_callback_t *info_cb,
859	void *info_cb_rock);
860
861
862/*********************************************************
863 * user canonicalization plug-in -- added cjn 1999-09-29 *
864 *********************************************************/
865
866typedef struct sasl_canonuser {
867    /* optional features of plugin (set to 0) */
868    int features;
869
870    /* spare integer (set to 0) */
871    int spare_int1;
872
873    /* global state for plugin */
874    void *glob_context;
875
876    /* name of plugin */
877    char *name;
878
879    /* free global state for plugin */
880    void (*canon_user_free)(void *glob_context, const sasl_utils_t *utils);
881
882    /* canonicalize a username
883     *  glob_context     -- global context from this structure
884     *  sparams          -- server params, note user_realm&propctx elements
885     *  user             -- user to login as (may not be NUL terminated)
886     *  len              -- length of user name (0 = strlen(user))
887     *  flags            -- for SASL_CU_* flags
888     *  out              -- buffer to copy user name
889     *  out_max          -- max length of user name
890     *  out_len          -- set to length of user name
891     *
892     *  note that the output buffers MAY be the same as the input buffers.
893     *
894     * returns
895     *  SASL_OK         on success
896     *  SASL_BADPROT    username contains invalid character
897     */
898    int (*canon_user_server)(void *glob_context,
899			     sasl_server_params_t *sparams,
900			     const char *user, unsigned len,
901			     unsigned flags,
902			     char *out,
903			     unsigned out_umax, unsigned *out_ulen);
904
905    int (*canon_user_client)(void *glob_context,
906			     sasl_client_params_t *cparams,
907			     const char *user, unsigned len,
908			     unsigned flags,
909			     char *out,
910			     unsigned out_max, unsigned *out_len);
911
912    /* for additions which don't require a version upgrade; set to 0 */
913    int (*spare_fptr1)(void);
914    int (*spare_fptr2)(void);
915    int (*spare_fptr3)(void);
916} sasl_canonuser_plug_t;
917
918#define SASL_CANONUSER_PLUG_VERSION 5
919
920/* default name for canonuser plug-in entry point is "sasl_canonuser_init"
921 *  similar to sasl_server_plug_init model, except only returns one
922 *  sasl_canonuser_plug_t structure;
923 */
924typedef int sasl_canonuser_init_t(const sasl_utils_t *utils,
925				  int max_version,
926				  int *out_version,
927				  sasl_canonuser_plug_t **plug,
928				  const char *plugname);
929
930/* add a canonuser plugin
931 */
932LIBSASL_API int sasl_canonuser_add_plugin(const char *plugname,
933				  sasl_canonuser_init_t *canonuserfunc);
934
935/******************************************************
936 * auxiliary property plug-in -- added cjn 1999-09-29 *
937 ******************************************************/
938
939typedef struct sasl_auxprop_plug {
940    /* optional features of plugin (none defined yet, set to 0) */
941    int features;
942
943    /* spare integer, must be set to 0 */
944    int spare_int1;
945
946    /* global state for plugin */
947    void *glob_context;
948
949    /* free global state for plugin (OPTIONAL) */
950    void (*auxprop_free)(void *glob_context, const sasl_utils_t *utils);
951
952    /* fill in fields of an auxiliary property context
953     *  last element in array has id of SASL_AUX_END
954     *  elements with non-0 len should be ignored.
955     */
956    // APPLE: union for v4 auxprop plugins
957    union {
958        int (*auxprop_lookup)(void *glob_context,
959			   sasl_server_params_t *sparams,
960			   unsigned flags,
961			   const char *user, unsigned ulen);
962        void (*auxprop_lookup_v4)(void *glob_context,
963			   sasl_server_params_t *sparams,
964			   unsigned flags,
965			   const char *user, unsigned ulen);
966    };
967
968    /* name of the auxprop plugin */
969    char *name;
970
971    /* store the fields/values of an auxiliary property context (OPTIONAL)
972     *
973     * if ctx is NULL, just check if storing properties is enabled
974     *
975     * returns
976     *  SASL_OK         on success
977     *  SASL_FAIL       on failure
978     */
979    int (*auxprop_store)(void *glob_context,
980			 sasl_server_params_t *sparams,
981			 struct propctx *ctx,
982			 const char *user, unsigned ulen);
983} sasl_auxprop_plug_t;
984
985/* auxprop lookup flags */
986#define SASL_AUXPROP_OVERRIDE 0x01 /* if clear, ignore auxiliary properties
987				    * with non-zero len field.  If set,
988				    * override value of those properties */
989#define SASL_AUXPROP_AUTHZID  0x02 /* if clear, we are looking up the
990				    * authid flags (prefixed with *), otherwise
991				    * we are looking up the authzid flags
992				    * (no prefix) */
993
994/* NOTE: Keep in sync with SASL_CU_<XXX> flags */
995#define SASL_AUXPROP_VERIFY_AGAINST_HASH 0x10
996
997
998#define SASL_AUXPROP_PLUG_VERSION  8
999#define SASL_AUXPROP_PLUG_MIN_VERSION  4
1000
1001/* default name for auxprop plug-in entry point is "sasl_auxprop_init"
1002 *  similar to sasl_server_plug_init model, except only returns one
1003 *  sasl_auxprop_plug_t structure;
1004 */
1005typedef int sasl_auxprop_init_t(const sasl_utils_t *utils,
1006				int max_version,
1007				int *out_version,
1008				sasl_auxprop_plug_t **plug,
1009				const char *plugname);
1010
1011/* add an auxiliary property plug-in
1012 */
1013LIBSASL_API int sasl_auxprop_add_plugin(const char *plugname,
1014					sasl_auxprop_init_t *auxpropfunc);
1015/* APPLE */
1016LIBSASL_API int sasl_auxprop_add_plugin_nolog(const char *plugname,
1017					sasl_auxprop_init_t *auxpropfunc);
1018
1019typedef void auxprop_info_callback_t (sasl_auxprop_plug_t *m,
1020			              sasl_info_callback_stage_t stage,
1021				      void *rock);
1022
1023/* Dump information about available auxprop plugins (separate functions are
1024   used for canon and server authentication plugins) */
1025LIBSASL_API int auxprop_plugin_info (const char *mech_list,
1026	auxprop_info_callback_t *info_cb,
1027	void *info_cb_rock);
1028
1029#ifdef __cplusplus
1030}
1031#endif
1032
1033#endif /* SASLPLUG_H */
1034