xref: /illumos-gate/usr/src/lib/libsasl/include/sasl.h (revision 1da57d55)
1 /*
2  * Copyright 2003 Sun Microsystems, Inc.  All rights reserved.
3  * Use is subject to license terms.
4  */
5 
6 /*
7  * *******************************IMPORTANT******************************
8  * send email to chris.newman@sun.com and cyrus-bugs@andrew.cmu.edu     *
9  * if you need to add new error codes, callback types, property values, *
10  * etc.   It is important to keep the multiple implementations of this  *
11  * API from diverging.                                                  *
12  * *******************************IMPORTANT******************************
13  *
14  * Basic Type Summary:
15  *  sasl_conn_t       Context for a SASL connection negotiation
16  *  sasl_ssf_t        Security layer Strength Factor
17  *  sasl_callback_t   A typed client/server callback function and context
18  *  sasl_interact_t   A client interaction descriptor
19  *  sasl_secret_t     A client password
20  *  sasl_rand_t       Random data context structure
21  *  sasl_security_properties_t  An application's required security level
22  *
23  * Callbacks:
24  *  sasl_getopt_t     client/server: Get an option value
25  *  sasl_canon_user_t client/server: Canonicalize username
26  *  sasl_log_t        client/server: Log message handler
27  *  sasl_verifyfile_t client/server: Verify file for specified usage
28  *  sasl_getpath_t    client/server: Get sasl search path
29  *
30  * Client only Callbacks:
31  *  sasl_getrealm_t   client: Get available realms
32  *  sasl_getsimple_t  client: Get user/language list
33  *  sasl_getsecret_t  client: Get authentication secret
34  *  sasl_chalprompt_t client: Display challenge and prompt for response
35  *
36  * Server only Callbacks:
37  *  sasl_authorize_t               user authorization policy callback
38  *  sasl_server_userdb_checkpass_t check password and auxprops in userdb
39  *  sasl_server_userdb_setpass_t   set password in userdb
40  *
41  * Client/Server Function Summary:
42  *  sasl_done         Release all SASL global state
43  *  sasl_dispose      Connection done: Dispose of sasl_conn_t
44  *  sasl_getprop      Get property (e.g., user name, security layer info)
45  *  sasl_setprop      Set property (e.g., external ssf)
46  *  sasl_errdetail    Generate string from last error on connection
47  *  sasl_errstring    Translate sasl error code to a string
48  *  sasl_encode       Encode data to send using security layer
49  *  sasl_decode       Decode data received using security layer
50  *
51  * Utility functions:
52  *  sasl_encode64     Encode data to send using MIME base64 encoding
53  *  sasl_decode64     Decode data received using MIME base64 encoding
54  *  sasl_erasebuffer  Erase a buffer
55  *
56  * Client Function Summary:
57  *  sasl_client_init  Load and initialize client plug-ins (call once)
58  *  sasl_client_new   Initialize client connection context: sasl_conn_t
59  *  sasl_client_start Select mechanism for connection
60  *  sasl_client_step  Perform one authentication step
61  *
62  * Server Function Summary
63  *  sasl_server_init  Load and initialize server plug-ins (call once)
64  *  sasl_server_new   Initialize server connection context: sasl_conn_t
65  *  sasl_listmech     Create list of available mechanisms
66  *  sasl_server_start Begin an authentication exchange
67  *  sasl_server_step  Perform one authentication exchange step
68  *  sasl_checkpass    Check a plaintext passphrase
69  *  sasl_checkapop    Check an APOP challenge/response (uses pseudo "APOP"
70  *                    mechanism similar to CRAM-MD5 mechanism; optional)
71  *  sasl_user_exists  Check if user exists
72  *  sasl_setpass      Change a password or add a user entry
73  *  sasl_auxprop_request  Request auxiliary properties
74  *  sasl_auxprop_getctx   Get auxiliary property context for connection
75  *
76  * Basic client model:
77  *  1. client calls sasl_client_init() at startup to load plug-ins
78  *  2. when connection formed, call sasl_client_new()
79  *  3. once list of supported mechanisms received from server, client
80  *     calls sasl_client_start().  goto 4a
81  *  4. client calls sasl_client_step()
82  * [4a. If SASL_INTERACT, fill in prompts and goto 4
83  *      -- doesn't happen if callbacks provided]
84  *  4b. If SASL error, goto 7 or 3
85  *  4c. If SASL_OK, continue or goto 6 if last server response was success
86  *  5. send message to server, wait for response
87  *  5a. On data or success with server response, goto 4
88  *  5b. On failure goto 7 or 3
89  *  5c. On success with no server response continue
90  *  6. continue with application protocol until connection closes
91  *     call sasl_getprop/sasl_encode/sasl_decode() if using security layer
92  *  7. call sasl_dispose(), may return to step 2
93  *  8. call sasl_done() when program terminates
94  *
95  * Basic Server model:
96  *  1. call sasl_server_init() at startup to load plug-ins
97  *  2. On connection, call sasl_server_new()
98  *  3. call sasl_listmech() and send list to client]
99  *  4. after client AUTH command, call sasl_server_start(), goto 5a
100  *  5. call sasl_server_step()
101  *  5a. If SASL_CONTINUE, output to client, wait response, repeat 5
102  *  5b. If SASL error, then goto 7
103  *  5c. If SASL_OK, move on
104  *  6. continue with application protocol until connection closes
105  *     call sasl_getprop to get username
106  *     call sasl_getprop/sasl_encode/sasl_decode() if using security layer
107  *  7. call sasl_dispose(), may return to step 2
108  *  8. call sasl_done() when program terminates
109  *
110  * ***********************************************
111  * IMPORTANT NOTE: server realms / username syntax
112  *
113  * If a user name contains a "@", then the rightmost "@" in the user name
114  * separates the account name from the realm in which this account is
115  * located.  A single server may support multiple realms.  If the
116  * server knows the realm at connection creation time (e.g., a server
117  * with multiple IP addresses tightly binds one address to a specific
118  * realm) then that realm must be passed in the user_realm field of
119  * the sasl_server_new call.  If user_realm is non-empty and an
120  * unqualified user name is supplied, then the canon_user facility is
121  * expected to append "@" and user_realm to the user name.  The canon_user
122  * facility may treat other characters such as "%" as equivalent to "@".
123  *
124  * If the server forbids the use of "@" in user names for other
125  * purposes, this simplifies security validation.
126  */
127 
128 #ifndef	_SASL_SASL_H
129 #define	_SASL_SASL_H
130 
131 #ifndef	_SASL_PROP_H
132 #include <sasl/prop.h>
133 #endif
134 
135 #ifdef	__cplusplus
136 extern "C" {
137 #endif
138 
139 #define	SASL_VERSION_MAJOR 2
140 #define	SASL_VERSION_MINOR 1
141 #define	SASL_VERSION_STEP 15
142 
143 /*
144  * The following ifdef block is the standard way of creating macros
145  * which make exporting from a DLL simpler. All files within this DLL
146  * are compiled with the LIBSASL_EXPORTS symbol defined on the command
147  * line. this symbol should not be defined on any project that uses
148  * this DLL. This way any other project whose source files include
149  * this file see LIBSASL_API functions as being imported from a DLL,
150  * wheras this DLL sees symbols defined with this macro as being
151  * exported.
152  *
153  * Under Unix, life is simpler: we just need to mark library functions
154  * as extern.  (Technically, we don't even have to do that.)
155  */
156 #ifdef WIN32
157 #ifdef LIBSASL_EXPORTS
158 #define	LIBSASL_API  __declspec(dllexport)
159 #else /* LIBSASL_EXPORTS */
160 #define	LIBSASL_API  __declspec(dllimport)
161 #endif /* LIBSASL_EXPORTS */
162 #else /* WIN32 */
163 #define	LIBSASL_API extern
164 #endif /* WIN32 */
165 
166 /*
167  * Same as above, but used during a variable declaration. Only Unix definition
168  * is different, as we can't assign an initial value to an extern variable
169  */
170 #ifdef WIN32
171 #ifdef LIBSASL_EXPORTS
172 #define	LIBSASL_VAR  __declspec(dllexport)
173 #else /* LIBSASL_EXPORTS */
174 #define	LIBSASL_VAR  __declspec(dllimport)
175 #endif /* LIBSASL_EXPORTS */
176 #else /* WIN32 */
177 #define	LIBSASL_VAR
178 #endif /* WIN32 */
179 
180 /*
181  * Basic API
182  */
183 
184 /* SASL result codes: */
185 #define	SASL_CONTINUE	1   /* another step is needed in authentication */
186 #define	SASL_OK		0   /* successful result */
187 #define	SASL_FAIL	-1   /* generic failure */
188 #define	SASL_NOMEM	-2   /* memory shortage failure */
189 #define	SASL_BUFOVER	-3   /* overflowed buffer */
190 #define	SASL_NOMECH	-4   /* mechanism not supported */
191 #define	SASL_BADPROT	-5   /* bad protocol / cancel */
192 #define	SASL_NOTDONE	-6   /* can't request info until later in exchange */
193 #define	SASL_BADPARAM	-7   /* invalid parameter supplied */
194 #define	SASL_TRYAGAIN	-8   /* transient failure (e.g., weak key) */
195 #define	SASL_BADMAC	-9   /* integrity check failed */
196 #define	SASL_NOTINIT	-12  /* SASL library not initialized */
197 
198 /* -- client only codes -- */
199 #define	SASL_INTERACT	2   /* needs user interaction */
200 #define	SASL_BADSERV	-10  /* server failed mutual authentication step */
201 #define	SASL_WRONGMECH	-11  /* mechanism doesn't support requested feature */
202 
203 /* -- server only codes -- */
204 #define	SASL_BADAUTH	-13  /* authentication failure */
205 #define	SASL_NOAUTHZ	-14  /* authorization failure */
206 #define	SASL_TOOWEAK	-15  /* mechanism too weak for this user */
207 #define	SASL_ENCRYPT	-16  /* encryption needed to use mechanism */
208 #define	SASL_TRANS	-17  /* One time use of a plaintext password will */
209 				/* enable requested mechanism for user */
210 #define	SASL_EXPIRED	-18  /* passphrase expired, has to be reset */
211 #define	SASL_DISABLED	-19  /* account disabled */
212 #define	SASL_NOUSER	-20  /* user not found */
213 #define	SASL_BADVERS	-23  /* version mismatch with plug-in */
214 #define	SASL_UNAVAIL	-24  /* remote authentication server unavailable */
215 #define	SASL_NOVERIFY	-26  /* user exists, but no verifier for user */
216 
217 /* -- codes for password setting -- */
218 #define	SASL_PWLOCK	-21  /* passphrase locked */
219 #define	SASL_NOCHANGE	-22  /* requested change was not needed */
220 #define	SASL_WEAKPASS	-27  /* passphrase is too weak for security policy */
221 #define	SASL_NOUSERPASS	-28  /* user supplied passwords not permitted */
222 
223 /* max size of a sasl mechanism name */
224 #define	SASL_MECHNAMEMAX 20
225 
226 #ifdef _WIN32
227 /* Define to have the same layout as a WSABUF */
228 #ifndef STRUCT_IOVEC_DEFINED
229 #define	STRUCT_IOVEC_DEFINED 1
230 struct iovec {
231     long iov_len;
232     char *iov_base;
233 };
234 #endif
235 #else
236 struct iovec;				/* Defined in OS headers */
237 #endif
238 
239 
240 /* per-connection SASL negotiation state for client or server */
241 typedef struct sasl_conn sasl_conn_t;
242 
243 /*
244  * Plain text password structure.
245  *  len is the length of the password, data is the text.
246  */
247 typedef struct sasl_secret {
248     unsigned long len;
249     unsigned char data[1];		/* variable sized */
250 } sasl_secret_t;
251 
252 /* random data context structure */
253 typedef struct sasl_rand_s sasl_rand_t;
254 
255 
256 /*
257  * Configure Basic Services
258  */
259 
260 /*
261  * the following functions are used to adjust how allocation and mutexes work
262  * they must be called before all other SASL functions:
263  */
264 
265 /* The following function is obsolete */
266 /*
267  * memory allocation functions which may optionally be replaced:
268  */
269 typedef void *sasl_malloc_t(unsigned long);
270 typedef void *sasl_calloc_t(unsigned long, unsigned long);
271 typedef void *sasl_realloc_t(void *, unsigned long);
272 typedef void sasl_free_t(void *);
273 
274 LIBSASL_API void sasl_set_alloc(sasl_malloc_t *,
275 				sasl_calloc_t *,
276 				sasl_realloc_t *,
277 				sasl_free_t *);
278 
279 /* The following function is obsolete */
280 /*
281  * mutex functions which may optionally be replaced:
282  *  sasl_mutex_alloc allocates a mutex structure
283  *  sasl_mutex_lock blocks until mutex locked
284  *   returns -1 on deadlock or parameter error
285  *   returns 0 on success
286  *  sasl_mutex_unlock unlocks mutex if it's locked
287  *   returns -1 if not locked or parameter error
288  *   returns 0 on success
289  *  sasl_mutex_free frees a mutex structure
290  */
291 typedef void *sasl_mutex_alloc_t(void);
292 typedef int sasl_mutex_lock_t(void *mutex);
293 typedef int sasl_mutex_unlock_t(void *mutex);
294 typedef void sasl_mutex_free_t(void *mutex);
295 LIBSASL_API void sasl_set_mutex(sasl_mutex_alloc_t *, sasl_mutex_lock_t *,
296 				sasl_mutex_unlock_t *, sasl_mutex_free_t *);
297 
298 /*
299  * Security preference types
300  */
301 
302 /*
303  * security layer strength factor -- an unsigned integer usable by the caller
304  *  to specify approximate security layer strength desired.  Roughly
305  *  correlated to effective key length for encryption.
306  * 0   = no protection
307  * 1   = integrity protection only
308  * 40  = 40-bit DES or 40-bit RC2/RC4
309  * 56  = DES
310  * 112 = triple-DES
311  * 128 = 128-bit RC2/RC4/BLOWFISH
312  * 256 = baseline AES
313  */
314 typedef unsigned sasl_ssf_t;
315 
316 /* usage flags provided to sasl_server_new and sasl_client_new: */
317 #define	SASL_SUCCESS_DATA	0x0004 /* server supports data on success */
318 #define	SASL_NEED_PROXY		0x0008 /* require a mech that allows proxying */
319 
320 /*
321  * Security Property Types
322  */
323 
324 /*
325  * Structure specifying the client or server's security policy
326  * and optional additional properties.
327  */
328 
329 /* These are the various security flags apps can specify. */
330 /*
331  * NOPLAINTEXT          -- don't permit mechanisms susceptible to simple
332  *                         passive attack (e.g., PLAIN, LOGIN)
333  * NOACTIVE             -- protection from active (non-dictionary) attacks
334  *                         during authentication exchange.
335  *                         Authenticates server.
336  * NODICTIONARY         -- don't permit mechanisms susceptible to passive
337  *                         dictionary attack
338  * FORWARD_SECRECY      -- require forward secrecy between sessions
339  *                         (breaking one won't help break next)
340  * NOANONYMOUS          -- don't permit mechanisms that allow anonymous login
341  * PASS_CREDENTIALS     -- require mechanisms which pass client
342  *			   credentials, and allow mechanisms which can pass
343  *			   credentials to do so
344  * MUTUAL_AUTH          -- require mechanisms which provide mutual
345  *			   authentication
346  */
347 #define	SASL_SEC_NOPLAINTEXT		0x0001
348 #define	SASL_SEC_NOACTIVE		0x0002
349 #define	SASL_SEC_NODICTIONARY		0x0004
350 #define	SASL_SEC_FORWARD_SECRECY	0x0008
351 #define	SASL_SEC_NOANONYMOUS		0x0010
352 #define	SASL_SEC_PASS_CREDENTIALS	0x0020
353 #define	SASL_SEC_MUTUAL_AUTH		0x0040
354 #define	SASL_SEC_MAXIMUM		0x00FF
355 
356 typedef struct sasl_security_properties
357 {
358 	/*
359 	 * security strength factor
360 	 *  min_ssf	= minimum acceptable final level
361 	 *  max_ssf	= maximum acceptable final level
362 	 */
363     sasl_ssf_t min_ssf;
364     sasl_ssf_t max_ssf;
365 
366 	/*
367 	 * Maximum security layer receive buffer size.
368 	 *  0=security layer not supported
369 	 */
370     unsigned maxbufsize;
371 
372 /* bitfield for attacks to protect against */
373     unsigned security_flags;
374 
375 /* NULL terminated array of additional property names, values */
376     const char **property_names;
377     const char **property_values;
378 } sasl_security_properties_t;
379 
380 /*
381  * Callback types
382  */
383 
384 /*
385  * Extensible type for a client/server callbacks
386  *  id      -- identifies callback type
387  *  proc    -- procedure call arguments vary based on id
388  *  context -- context passed to procedure
389  */
390 /*
391  * Note that any memory that is allocated by the callback needs to be
392  * freed by the application, be it via function call or interaction.
393  *
394  * It may be freed after sasl_*_step returns SASL_OK.  if the mechanism
395  * requires this information to persist (for a security layer, for example)
396  * it must maintain a private copy.
397  */
398 typedef struct sasl_callback {
399 	/*
400 	 * Identifies the type of the callback function.
401 	 * Mechanisms must ignore callbacks with id's they don't recognize.
402 	 */
403     unsigned long id;
404     int (*proc)();   /* Callback function.  Types of arguments vary by 'id' */
405     void *context;
406 } sasl_callback_t;
407 
408 /*
409  * callback ids & functions:
410  */
411 #define	SASL_CB_LIST_END   0  /* end of list */
412 
413 /*
414  * option reading callback -- this allows a SASL configuration to be
415  *  encapsulated in the caller's configuration system.  Some implementations
416  *  may use default config file(s) if this is omitted.  Configuration items
417  *  may be plugin-specific and are arbitrary strings.
418  *
419  * inputs:
420  *  context     -- option context from callback record
421  *  plugin_name -- name of plugin (NULL = general SASL option)
422  *  option      -- name of option
423  * output:
424  *  result      -- set to result which persists until next getopt in
425  *                 same thread, unchanged if option not found
426  *  len         -- length of result (may be NULL)
427  * returns:
428  *  SASL_OK     -- no error
429  *  SASL_FAIL   -- error
430  */
431 typedef int sasl_getopt_t(void *context, const char *plugin_name,
432 			const char *option,
433 			const char **result, unsigned *len);
434 #define	SASL_CB_GETOPT	1
435 
436 /* Logging levels for use with the logging callback function. */
437 #define	SASL_LOG_NONE  0	/* don't log anything */
438 #define	SASL_LOG_ERR   1	/* log unusual errors (default) */
439 #define	SASL_LOG_FAIL  2	/* log all authentication failures */
440 #define	SASL_LOG_WARN  3	/* log non-fatal warnings */
441 #define	SASL_LOG_NOTE  4	/* more verbose than LOG_WARN */
442 #define	SASL_LOG_DEBUG 5	/* more verbose than LOG_NOTE */
443 #define	SASL_LOG_TRACE 6	/* traces of internal protocols */
444 #define	SASL_LOG_PASS  7	/* traces of internal protocols, including */
445 				/* passwords */
446 
447 /*
448  * logging callback -- this allows plugins and the middleware to
449  *  log operations they perform.
450  * inputs:
451  *  context     -- logging context from the callback record
452  *  level       -- logging level; see above
453  *  message     -- message to log
454  * returns:
455  *  SASL_OK     -- no error
456  *  SASL_FAIL   -- error
457  */
458 typedef int sasl_log_t(void *context,
459 			int level,
460 			const char *message);
461 #define	SASL_CB_LOG	    2
462 
463 /*
464  * getpath callback -- this allows applications to specify the
465  * colon-separated path to search for plugins (by default,
466  * taken from an implementation-specific location).
467  * inputs:
468  *  context     -- getpath context from the callback record
469  * outputs:
470  *  path	-- colon seperated path
471  * returns:
472  *  SASL_OK     -- no error
473  *  SASL_FAIL   -- error
474  */
475 typedef int sasl_getpath_t(void *context,
476 			    const char **path);
477 
478 #define	SASL_CB_GETPATH	    3
479 
480 /* Callback to get the location of the sasl config  */
481 #define	SASL_CB_GETCONF	    0x5001
482 
483 /*
484  * verify file callback -- this allows applications to check if they
485  * want SASL to use files, file by file.  This is intended to allow
486  * applications to sanity check the environment to make sure plugins
487  * or the configuration file can't be written to, etc.
488  * inputs:
489  *  context     -- verifypath context from the callback record
490  *  file        -- full path to file to verify
491  *  type        -- type of file to verify (see below)
492  *
493  * returns:
494  *  SASL_OK        -- no error (file can safely be used)
495  *  SASL_CONTINUE  -- continue WITHOUT using this file
496  *  SASL_FAIL      -- error
497  */
498 
499 /* these are the types of files libsasl will ask about */
500 typedef enum {
501     SASL_VRFY_PLUGIN = 0,	/* a DLL/shared library plug-in */
502     SASL_VRFY_CONF = 1,		/* a configuration file */
503     SASL_VRFY_PASSWD = 2,	/* a password storage file/db */
504     SASL_VRFY_OTHER = 3		/* some other file */
505 } sasl_verify_type_t;
506 
507 typedef int sasl_verifyfile_t(void *context,
508 			    const char *file, sasl_verify_type_t type);
509 #define	SASL_CB_VERIFYFILE  4
510 
511 
512 /* client/user interaction callbacks: */
513 /*
514  * Simple prompt -- result must persist until next call to getsimple on
515  *  same connection or until connection context is disposed
516  * inputs:
517  *  context       -- context from callback structure
518  *  id            -- callback id
519  * outputs:
520  *  result        -- set to NUL terminated string
521  *                   NULL = user cancel
522  *  len           -- length of result
523  * returns SASL_OK
524  */
525 typedef int sasl_getsimple_t(void *context, int id,
526 			    const char **result, unsigned *len);
527 #define	SASL_CB_USER		0x4001	/* client user identity to login as */
528 #define	SASL_CB_AUTHNAME	0x4002	/* client authentication name */
529 #define	SASL_CB_LANGUAGE	0x4003
530 					/*
531 					 * comma separated list of RFC 1766
532 					 * language codes in order of preference
533 					 * to be used to localize client prompts
534 					 * or server error codes
535 					 */
536 #define	SASL_CB_CNONCE		0x4007
537 	/* caller supplies client-nonce primarily for testing purposes */
538 
539 /*
540  * get a sasl_secret_t (plaintext password with length)
541  * inputs:
542  *  conn          -- connection context
543  *  context       -- context from callback structure
544  *  id            -- callback id
545  * outputs:
546  *  psecret       -- set to NULL to cancel
547  *                   set to password structure which must persist until
548  *                   next call to getsecret in same connection, but middleware
549  *                   will erase password data when it's done with it.
550  * returns SASL_OK
551  */
552 typedef int sasl_getsecret_t(sasl_conn_t *conn, void *context, int id,
553 			    sasl_secret_t **psecret);
554 #define	SASL_CB_PASS	0x4004	/* client passphrase-based secret */
555 
556 
557 /*
558  * prompt for input in response to a challenge.
559  * input:
560  *  context   -- context from callback structure
561  *  id        -- callback id
562  *  challenge -- server challenge
563  * output:
564  *  result    -- NUL terminated result, NULL = user cancel
565  *  len       -- length of result
566  * returns SASL_OK
567  */
568 typedef int sasl_chalprompt_t(void *context, int id,
569 			    const char *challenge,
570 			    const char *prompt, const char *defresult,
571 			    const char **result, unsigned *len);
572 #define	SASL_CB_ECHOPROMPT   0x4005 /* challenge and client enterred result */
573 #define	SASL_CB_NOECHOPROMPT 0x4006 /* challenge and client enterred result */
574 
575 /*
576  * prompt (or autoselect) the realm to do authentication in.
577  *  may get a list of valid realms.
578  * input:
579  *  context     -- context from callback structure
580  *  id          -- callback id
581  *  availrealms -- available realms; string list; NULL terminated
582  *                 list may be empty.
583  * output:
584  *  result      -- NUL terminated realm; NULL is equivalent to ""
585  * returns SASL_OK
586  * result must persist until the next callback
587  */
588 typedef int sasl_getrealm_t(void *context, int id,
589 			    const char **availrealms,
590 			    const char **result);
591 #define	SASL_CB_GETREALM (0x4008) /* realm to attempt authentication in */
592 
593 /* server callbacks: */
594 
595 /*
596  * improved callback to verify authorization;
597  *     canonicalization now handled elsewhere
598  *  conn           -- connection context
599  *  requested_user -- the identity/username to authorize (NUL terminated)
600  *  rlen           -- length of requested_user
601  *  auth_identity  -- the identity associated with the secret (NUL terminated)
602  *  alen           -- length of auth_identity
603  *  default_realm  -- default user realm, as passed to sasl_server_new if
604  *  urlen          -- length of default realm
605  *  propctx        -- auxiliary properties
606  * returns SASL_OK on success,
607  *         SASL_NOAUTHZ or other SASL response on failure
608  */
609 typedef int sasl_authorize_t(sasl_conn_t *conn,
610 			    void *context,
611 			    const char *requested_user, unsigned rlen,
612 			    const char *auth_identity, unsigned alen,
613 			    const char *def_realm, unsigned urlen,
614 			    struct propctx *propctx);
615 #define	SASL_CB_PROXY_POLICY 0x8001
616 
617 /*
618  * functions for "userdb" based plugins to call to get/set passwords.
619  * the location for the passwords is determined by the caller or middleware.
620  * plug-ins may get passwords from other locations.
621  */
622 
623 /*
624  * callback to verify a plaintext password against the caller-supplied
625  * user database.  This is necessary to allow additional <method>s for
626  * encoding of the userPassword property.
627  *  user          -- NUL terminated user name with user@realm syntax
628  *  pass          -- password to check (may not be NUL terminated)
629  *  passlen       -- length of password to check
630  *  propctx       -- auxiliary properties for user
631  */
632 typedef int sasl_server_userdb_checkpass_t(sasl_conn_t *conn,
633 					    void *context,
634 					    const char *user,
635 					    const char *pass,
636 					    unsigned passlen,
637 					    struct propctx *propctx);
638 #define	SASL_CB_SERVER_USERDB_CHECKPASS (0x8005)
639 
640 /*
641  * callback to store/change a plaintext password in the user database
642  *  user          -- NUL terminated user name with user@realm syntax
643  *  pass          -- password to store (may not be NUL terminated)
644  *  passlen       -- length of password to store
645  *  propctx       -- auxiliary properties (not stored)
646  *  flags         -- see SASL_SET_* flags below (SASL_SET_CREATE optional)
647  */
648 typedef int sasl_server_userdb_setpass_t(sasl_conn_t *conn,
649 					void *context,
650 					const char *user,
651 					const char *pass,
652 					unsigned passlen,
653 					struct propctx *propctx,
654 					unsigned flags);
655 #define	SASL_CB_SERVER_USERDB_SETPASS (0x8006)
656 
657 /*
658  * callback for a server-supplied user canonicalization function.
659  *
660  * This function is called directly after the mechanism has the
661  * authentication and authorization IDs.  It is called before any
662  * User Canonicalization plugin is called.  It has the responsibility
663  * of copying its output into the provided output buffers.
664  *
665  *  in, inlen     -- user name to canonicalize, may not be NUL terminated
666  *                   may be same buffer as out
667  *  flags         -- not currently used, supplied by auth mechanism
668  *  user_realm    -- the user realm (may be NULL in case of client)
669  *  out           -- buffer to copy user name
670  *  out_max       -- max length of user name
671  *  out_len       -- set to length of user name
672  *
673  * returns
674  *  SASL_OK         on success
675  *  SASL_BADPROT    username contains invalid character
676  */
677 
678 /* User Canonicalization Function Flags */
679 
680 #define	SASL_CU_NONE    0x00 /* Not a valid flag to pass */
681 /* One of the following two is required */
682 #define	SASL_CU_AUTHID  0x01
683 #define	SASL_CU_AUTHZID 0x02
684 
685 typedef int sasl_canon_user_t(sasl_conn_t *conn,
686 			    void *context,
687 			    const char *in, unsigned inlen,
688 			    unsigned flags,
689 			    const char *user_realm,
690 			    char *out,
691 			    unsigned out_max, unsigned *out_len);
692 
693 #define	SASL_CB_CANON_USER (0x8007)
694 
695 /*
696  * Common Client/server functions
697  */
698 
699 /*
700  * get sasl library version information
701  * implementation is a vendor-defined string
702  * version is a vender-defined representation of the version #
703  */
704 LIBSASL_API void sasl_version(const char **implementation,
705 			    int *version);
706 
707 /*
708  * dispose of all SASL plugins.  Connection
709  * states have to be disposed of before calling this.
710  */
711 LIBSASL_API void sasl_done(void);
712 
713 /*
714  * dispose connection state, sets it to NULL
715  *  checks for pointer to NULL
716  */
717 LIBSASL_API void sasl_dispose(sasl_conn_t **pconn);
718 
719 /*
720  * translate an error number into a string
721  * input:
722  *  saslerr  -- the error number
723  *  langlist -- comma separated list of RFC 1766 languages (may be NULL)
724  * results:
725  *  outlang  -- the language actually used (may be NULL if don't care)
726  * returns:
727  *  the error message in UTF-8 (only the US-ASCII subset if langlist is NULL)
728  */
729 LIBSASL_API const char *sasl_errstring(int saslerr,
730 					const char *langlist,
731 					const char **outlang);
732 
733 /*
734  * get detail about the last error that occurred on a connection
735  * text is sanitized so it's suitable to send over the wire
736  * (e.g., no distinction between SASL_BADAUTH and SASL_NOUSER)
737  * input:
738  *  conn          -- mandatory connection context
739  * returns:
740  *  the error message in UTF-8 (only the US-ASCII subset permitted if no
741  *  SASL_CB_LANGUAGE callback is present)
742  */
743 LIBSASL_API const char *sasl_errdetail(sasl_conn_t *conn);
744 
745 /*
746  * set the error string which will be returned by sasl_errdetail() using
747  *  syslog()-style formatting (e.g. printf-style with %m as most recent
748  *  errno error)
749  *
750  *  primarily for use by server callbacks such as the sasl_authorize_t
751  *  callback and internally to plug-ins
752  *
753  * This will also trigger a call to the SASL logging callback (if any)
754  * with a level of SASL_LOG_FAIL unless the SASL_NOLOG flag is set.
755  *
756  * Messages should be sensitive to the current language setting.  If there
757  * is no SASL_CB_LANGUAGE callback messages MUST be US-ASCII otherwise UTF-8
758  * is used and use of RFC 2482 for mixed-language text is encouraged.
759  *
760  * if conn is NULL, function does nothing
761  */
762 LIBSASL_API void sasl_seterror(sasl_conn_t *conn, unsigned flags,
763 				const char *fmt, ...);
764 #define	SASL_NOLOG	0x01
765 
766 /*
767  * get property from SASL connection state
768  *  propnum       -- property number
769  *  pvalue        -- pointer to value
770  * returns:
771  *  SASL_OK       -- no error
772  *  SASL_NOTDONE  -- property not available yet
773  *  SASL_BADPARAM -- bad property number
774  */
775 LIBSASL_API int sasl_getprop(sasl_conn_t *conn, int propnum,
776 			    const void **pvalue);
777 #define	SASL_USERNAME	0	/* pointer to NUL terminated user name */
778 #define	SASL_SSF	1	/* security layer security strength factor, */
779 				/* if 0, call to sasl_encode, sasl_decode */
780 				/* unnecessary */
781 #define	SASL_MAXOUTBUF	2	/* security layer max output buf unsigned */
782 #define	SASL_DEFUSERREALM 3	/* default realm passed to server_new */
783 				/* or set with setprop */
784 #define	SASL_GETOPTCTX	4	/* context for getopt callback */
785 #define	SASL_CALLBACK	7	/* current callback function list */
786 #define	SASL_IPLOCALPORT 8	/* iplocalport string passed to server_new */
787 #define	SASL_IPREMOTEPORT 9	/* ipremoteport string passed to server_new */
788 #define	SASL_SERVICE	12	/* service passed to sasl_*_new */
789 #define	SASL_SERVERFQDN	13	/* serverFQDN passed to sasl_*_new */
790 #define	SASL_AUTHSOURCE   14	/* name of auth source last used, useful */
791 				/* for failed authentication tracking */
792 #define	SASL_MECHNAME	15	/* active mechanism name, if any */
793 #define	SASL_AUTHUSER	16	/* authentication/admin user */
794 
795 /*
796  * This returns a string which is either empty or has an error message
797  * from sasl_seterror (e.g., from a plug-in or callback).  It differs
798  * from the result of sasl_errdetail() which also takes into account the
799  * last return status code.
800  */
801 #define	SASL_PLUGERR	10
802 
803 /*
804  * set property in SASL connection state
805  * returns:
806  *  SASL_OK       -- value set
807  *  SASL_BADPARAM -- invalid property or value
808  */
809 LIBSASL_API int sasl_setprop(sasl_conn_t *conn,
810 			    int propnum,
811 			    const void *value);
812 #define	SASL_SSF_EXTERNAL  100	/* external SSF active (sasl_ssf_t *) */
813 #define	SASL_SEC_PROPS	   101	/* sasl_security_properties_t */
814 #define	SASL_AUTH_EXTERNAL 102	/* external authentication ID (const char *) */
815 
816 /*
817  * If the SASL_AUTH_EXTERNAL value is non-NULL, then a special version of the
818  * EXTERNAL mechanism is enabled (one for server-embedded EXTERNAL mechanisms).
819  * Otherwise, the EXTERNAL mechanism will be absent unless a plug-in
820  * including EXTERNAL is present.
821  */
822 
823 /*
824  * do precalculations during an idle period or network round trip
825  *  may pass NULL to precompute for some mechanisms prior to connect
826  *  returns 1 if action taken, 0 if no action taken
827  */
828 LIBSASL_API int sasl_idle(sasl_conn_t *conn);
829 
830 /*
831  * Client API
832  */
833 
834 /*
835  * list of client interactions with user for caller to fill in
836  */
837 typedef struct sasl_interact {
838     unsigned long id;		/* same as client/user callback ID */
839     const char *challenge;	/* presented to user (e.g. OTP challenge) */
840     const char *prompt;		/* presented to user (e.g. "Username: ") */
841     const char *defresult;	/* default result string */
842     const void *result;		/* set to point to result */
843     unsigned len;		/* set to length of result */
844 } sasl_interact_t;
845 
846 /*
847  * initialize the SASL client drivers
848  *  callbacks      -- base callbacks for all client connections;
849  *                    must include getopt callback
850  * returns:
851  *  SASL_OK        -- Success
852  *  SASL_NOMEM     -- Not enough memory
853  *  SASL_BADVERS   -- Mechanism version mismatch
854  *  SASL_BADPARAM  -- missing getopt callback or error in config file
855  *  SASL_NOMECH    -- No mechanisms available
856  *  ...
857  */
858 LIBSASL_API int sasl_client_init(const sasl_callback_t *callbacks);
859 
860 /*
861  * initialize a client exchange based on the specified mechanism
862  *  service       -- registered name of the service using SASL (e.g. "imap")
863  *  serverFQDN    -- the fully qualified domain name of the server
864  *  iplocalport   -- client IPv4/IPv6 domain literal string with port
865  *                    (if NULL, then mechanisms requiring IPaddr are disabled)
866  *  ipremoteport  -- server IPv4/IPv6 domain literal string with port
867  *                    (if NULL, then mechanisms requiring IPaddr are disabled)
868  *  prompt_supp   -- list of client interactions supported
869  *                   may also include sasl_getopt_t context & call
870  *                   NULL prompt_supp = user/pass via SASL_INTERACT only
871  *                   NULL proc = interaction supported via SASL_INTERACT
872  *  flags         -- server usage flags (see above)
873  * out:
874  *  pconn         -- sasl connection
875  *
876  * Returns:
877  *  SASL_OK       -- success
878  *  SASL_NOMECH   -- no mechanism meets requested properties
879  *  SASL_NOMEM    -- not enough memory
880  */
881 LIBSASL_API int sasl_client_new(const char *service,
882 				const char *serverFQDN,
883 				const char *iplocalport,
884 				const char *ipremoteport,
885 				const sasl_callback_t *prompt_supp,
886 				unsigned flags,
887 				sasl_conn_t **pconn);
888 
889 /*
890  * select a mechanism for a connection
891  *  mechlist      -- list of mechanisms to use (punctuation ignored)
892  * output:
893  *  prompt_need   -- on SASL_INTERACT, list of prompts needed to continue
894  *                   may be NULL if callbacks provided
895  *  clientout     -- the initial client response to send to the server
896  *                   will be valid until next call to client_start/client_step
897  *                   NULL if mech doesn't include initial client challenge
898  *  mech          -- set to mechansm name of selected mechanism (may be NULL)
899  *
900  * Returns:
901  *  SASL_OK       -- success
902  *  SASL_NOMEM    -- not enough memory
903  *  SASL_NOMECH   -- no mechanism meets requested properties
904  *  SASL_INTERACT -- user interaction needed to fill in prompt_need list
905  */
906 LIBSASL_API int sasl_client_start(sasl_conn_t *conn,
907 				const char *mechlist,
908 				sasl_interact_t **prompt_need,
909 				const char **clientout,
910 				unsigned *clientoutlen,
911 				const char **mech);
912 
913 /*
914  * do a single authentication step.
915  *  serverin    -- the server message received by the client, MUST have a NUL
916  *                 sentinel, not counted by serverinlen
917  * output:
918  *  prompt_need -- on SASL_INTERACT, list of prompts needed to continue
919  *  clientout   -- the client response to send to the server
920  *                 will be valid until next call to client_start/client_step
921  *
922  * returns:
923  *  SASL_OK        -- success
924  *  SASL_INTERACT  -- user interaction needed to fill in prompt_need list
925  *  SASL_BADPROT   -- server protocol incorrect/cancelled
926  *  SASL_BADSERV   -- server failed mutual auth
927  */
928 LIBSASL_API int sasl_client_step(sasl_conn_t *conn,
929 				const char *serverin,
930 				unsigned serverinlen,
931 				sasl_interact_t **prompt_need,
932 				const char **clientout,
933 				unsigned *clientoutlen);
934 
935 /*
936  * Server API
937  */
938 
939 /*
940  * initialize server drivers, done once per process
941  *  callbacks      -- callbacks for all server connections; must include
942  *                    getopt callback
943  *  appname        -- name of calling application (for lower level logging)
944  * results:
945  *  state          -- server state
946  * returns:
947  *  SASL_OK        -- success
948  *  SASL_BADPARAM  -- error in config file
949  *  SASL_NOMEM     -- memory failure
950  *  SASL_BADVERS   -- Mechanism version mismatch
951  */
952 LIBSASL_API int sasl_server_init(const sasl_callback_t *callbacks,
953 				const char *appname);
954 
955 /*
956  * IP/port syntax:
957  *  a.b.c.d:p                where a-d are 0-255 and p is 0-65535 port number.
958  *  [e:f:g:h:i:j:k:l]:p      where e-l are 0000-ffff lower-case hexidecimal
959  *  [e:f:g:h:i:j:a.b.c.d]:p  alternate syntax for previous
960  *
961  *  Note that one or more "0" fields in f-k can be replaced with "::"
962  *  Thus:                 [e:f:0000:0000:0000:j:k:l]:p
963  *  can be abbreviated:   [e:f::j:k:l]:p
964  *
965  * A buffer of size 52 is adequate for the longest format with NUL terminator.
966  */
967 
968 /*
969  * create context for a single SASL connection
970  *  service        -- registered name of the service using SASL (e.g. "imap")
971  *  serverFQDN     -- Fully qualified domain name of server.  NULL means use
972  *                    gethostname() or equivalent.
973  *                    Useful for multi-homed servers.
974  *  user_realm     -- permits multiple user realms on server, NULL = default
975  *  iplocalport    -- server IPv4/IPv6 domain literal string with port
976  *                    (if NULL, then mechanisms requiring IPaddr are disabled)
977  *  ipremoteport   -- client IPv4/IPv6 domain literal string with port
978  *                    (if NULL, then mechanisms requiring IPaddr are disabled)
979  *  callbacks      -- callbacks (e.g., authorization, lang, new getopt context)
980  *  flags          -- usage flags (see above)
981  * returns:
982  *  pconn          -- new connection context
983  *
984  * returns:
985  *  SASL_OK        -- success
986  *  SASL_NOMEM     -- not enough memory
987  */
988 LIBSASL_API int sasl_server_new(const char *service,
989 				const char *serverFQDN,
990 				const char *user_realm,
991 				const char *iplocalport,
992 				const char *ipremoteport,
993 				const sasl_callback_t *callbacks,
994 				unsigned flags,
995 				sasl_conn_t **pconn);
996 
997 /* The following function is obsolete */
998 /*
999  * Return an array of NUL-terminated strings, terminated by a NULL pointer,
1000  * which lists all possible mechanisms that the library can supply
1001  *
1002  * Returns NULL on failure.
1003  */
1004 LIBSASL_API const char ** sasl_global_listmech(void);
1005 
1006 /*
1007  * This returns a list of mechanisms in a NUL-terminated string
1008  *  conn          -- the connection to list mechanisms for (either client
1009  *                   or server)
1010  *  user          -- restricts mechanisms to those available to that user
1011  *                   (may be NULL, not used for client case)
1012  *  prefix        -- appended to beginning of result
1013  *  sep           -- appended between mechanisms
1014  *  suffix        -- appended to end of result
1015  * results:
1016  *  result        -- NUL terminated result which persists until next
1017  *                   call to sasl_listmech for this sasl_conn_t
1018  *  plen          -- gets length of result (excluding NUL), may be NULL
1019  *  pcount        -- gets number of mechanisms, may be NULL
1020  *
1021  * returns:
1022  *  SASL_OK        -- success
1023  *  SASL_NOMEM     -- not enough memory
1024  *  SASL_NOMECH    -- no enabled mechanisms
1025  */
1026 LIBSASL_API int sasl_listmech(sasl_conn_t *conn,
1027 			    const char *user,
1028 			    const char *prefix,
1029 			    const char *sep,
1030 			    const char *suffix,
1031 			    const char **result,
1032 			    unsigned *plen,
1033 			    int *pcount);
1034 
1035 /*
1036  * start a mechanism exchange within a connection context
1037  *  mech           -- the mechanism name client requested
1038  *  clientin       -- client initial response (NUL terminated), NULL if empty
1039  *  clientinlen    -- length of initial response
1040  *  serverout      -- initial server challenge, NULL if done
1041  *                    (library handles freeing this string)
1042  *  serveroutlen   -- length of initial server challenge
1043  * output:
1044  *  pconn          -- the connection negotiation state on success
1045  *
1046  * Same returns as sasl_server_step() or
1047  * SASL_NOMECH if mechanism not available.
1048  */
1049 LIBSASL_API int sasl_server_start(sasl_conn_t *conn,
1050 				const char *mech,
1051 				const char *clientin,
1052 				unsigned clientinlen,
1053 				const char **serverout,
1054 				unsigned *serveroutlen);
1055 
1056 /*
1057  * perform one step of the SASL exchange
1058  *  inputlen & input -- client data
1059  *                      NULL on first step if no optional client step
1060  *  outputlen & output -- set to the server data to transmit
1061  *                        to the client in the next step
1062  *                        (library handles freeing this)
1063  *
1064  * returns:
1065  *  SASL_OK        -- exchange is complete.
1066  *  SASL_CONTINUE  -- indicates another step is necessary.
1067  *  SASL_TRANS     -- entry for user exists, but not for mechanism
1068  *                    and transition is possible
1069  *  SASL_BADPARAM  -- service name needed
1070  *  SASL_BADPROT   -- invalid input from client
1071  *  ...
1072  */
1073 LIBSASL_API int sasl_server_step(sasl_conn_t *conn,
1074 				const char *clientin,
1075 				unsigned clientinlen,
1076 				const char **serverout,
1077 				unsigned *serveroutlen);
1078 
1079 /* The following function is obsolete */
1080 /*
1081  * check if an apop exchange is valid
1082  *  (note this is an optional part of the SASL API)
1083  *  if challenge is NULL, just check if APOP is enabled
1084  * inputs:
1085  *  challenge     -- challenge which was sent to client
1086  *  challen       -- length of challenge, 0 = strlen(challenge)
1087  *  response      -- client response, "<user> <digest>" (RFC 1939)
1088  *  resplen       -- length of response, 0 = strlen(response)
1089  * returns
1090  *  SASL_OK       -- success
1091  *  SASL_BADAUTH  -- authentication failed
1092  *  SASL_BADPARAM -- missing challenge
1093  *  SASL_BADPROT  -- protocol error (e.g., response in wrong format)
1094  *  SASL_NOVERIFY -- user found, but no verifier
1095  *  SASL_NOMECH   -- mechanism not supported
1096  *  SASL_NOUSER   -- user not found
1097  */
1098 LIBSASL_API int sasl_checkapop(sasl_conn_t *conn,
1099 				const char *challenge, unsigned challen,
1100 				const char *response, unsigned resplen);
1101 
1102 /*
1103  * check if a plaintext password is valid
1104  *   if user is NULL, check if plaintext passwords are enabled
1105  * inputs:
1106  *  user          -- user to query in current user_domain
1107  *  userlen       -- length of username, 0 = strlen(user)
1108  *  pass          -- plaintext password to check
1109  *  passlen       -- length of password, 0 = strlen(pass)
1110  * returns
1111  *  SASL_OK       -- success
1112  *  SASL_NOMECH   -- mechanism not supported
1113  *  SASL_NOVERIFY -- user found, but no verifier
1114  *  SASL_NOUSER   -- user not found
1115  */
1116 LIBSASL_API int sasl_checkpass(sasl_conn_t *conn,
1117 				const char *user, unsigned userlen,
1118 				const char *pass, unsigned passlen);
1119 
1120 /*
1121  * check if a user exists on server
1122  *  conn          -- connection context
1123  *  service       -- registered name of the service using SASL (e.g. "imap")
1124  *  user_realm    -- permits multiple user realms on server, NULL = default
1125  *  user          -- NUL terminated user name
1126  *
1127  * returns:
1128  *  SASL_OK       -- success
1129  *  SASL_DISABLED -- account disabled
1130  *  SASL_NOUSER   -- user not found
1131  *  SASL_NOVERIFY -- user found, but no usable mechanism
1132  *  SASL_NOMECH   -- no mechanisms enabled
1133  */
1134 LIBSASL_API int sasl_user_exists(sasl_conn_t *conn,
1135 				const char *service,
1136 				const char *user_realm,
1137 				const char *user);
1138 
1139 /*
1140  * set the password for a user
1141  *  conn        -- SASL connection
1142  *  user        -- user name
1143  *  pass        -- plaintext password, may be NULL to remove user
1144  *  passlen     -- length of password, 0 = strlen(pass)
1145  *  oldpass     -- NULL will sometimes work
1146  *  oldpasslen  -- length of password, 0 = strlen(oldpass)
1147  *  flags       -- see flags below
1148  *
1149  * returns:
1150  *  SASL_NOCHANGE  -- proper entry already exists
1151  *  SASL_NOMECH    -- no authdb supports password setting as configured
1152  *  SASL_NOVERIFY  -- user exists, but no settable password present
1153  *  SASL_DISABLED  -- account disabled
1154  *  SASL_PWLOCK    -- password locked
1155  *  SASL_WEAKPASS  -- password too weak for security policy
1156  *  SASL_NOUSERPASS -- user-supplied passwords not permitted
1157  *  SASL_FAIL      -- OS error
1158  *  SASL_BADPARAM  -- password too long
1159  *  SASL_OK        -- successful
1160  */
1161 LIBSASL_API int sasl_setpass(sasl_conn_t *conn,
1162 			    const char *user,
1163 			    const char *pass, unsigned passlen,
1164 			    const char *oldpass, unsigned oldpasslen,
1165 			    unsigned flags);
1166 #define	SASL_SET_CREATE  0x01   /* create a new entry for user */
1167 #define	SASL_SET_REMOVE  SASL_SET_CREATE /* remove user if pass is NULL */
1168 #define	SASL_SET_DISABLE 0x02	/* disable user account */
1169 
1170 /*
1171  * Auxiliary Property Support -- added by cjn 1999-09-29
1172  */
1173 
1174 #define	SASL_AUX_END	NULL	/* last auxiliary property */
1175 
1176 /* traditional Posix items (should be implemented on Posix systems) */
1177 #define	SASL_AUX_PASSWORD "*userPassword" /* User Password (of authid) */
1178 #define	SASL_AUX_UIDNUM   "uidNumber"	/* UID number for the user */
1179 #define	SASL_AUX_GIDNUM   "gidNumber"	/* GID for the user */
1180 #define	SASL_AUX_FULLNAME "gecos"	/* full name of the user, unix-style */
1181 #define	SASL_AUX_HOMEDIR  "homeDirectory" /* home directory for user */
1182 #define	SASL_AUX_SHELL    "loginShell"	/* login shell for the user */
1183 
1184 /* optional additional items (not necessarily implemented) */
1185 /*
1186  * single preferred mail address for user canonically-quoted
1187  * RFC821/822 syntax
1188  */
1189 #define	SASL_AUX_MAILADDR "mail"
1190 /* path to unix-style mailbox for user */
1191 #define	SASL_AUX_UNIXMBX  "mailMessageStore"
1192 /* SMTP mail channel name to use if user authenticates successfully */
1193 #define	SASL_AUX_MAILCHAN "mailSMTPSubmitChannel"
1194 
1195 /*
1196  * Request a set of auxiliary properties
1197  *  conn         connection context
1198  *  propnames    list of auxiliary property names to request ending with
1199  *               NULL.
1200  *
1201  * Subsequent calls will add items to the request list.  Call with NULL
1202  * to clear the request list.
1203  *
1204  * errors
1205  *  SASL_OK       -- success
1206  *  SASL_BADPARAM -- bad count/conn parameter
1207  *  SASL_NOMEM    -- out of memory
1208  */
1209 LIBSASL_API int sasl_auxprop_request(sasl_conn_t *conn,
1210 				    const char **propnames);
1211 
1212 /*
1213  * Returns current auxiliary property context.
1214  * Use functions in prop.h to access content
1215  *
1216  *  if authentication hasn't completed, property values may be empty/NULL
1217  *
1218  *  properties not recognized by active plug-ins will be left empty/NULL
1219  *
1220  *  returns NULL if conn is invalid.
1221  */
1222 LIBSASL_API struct propctx *sasl_auxprop_getctx(sasl_conn_t *conn);
1223 
1224 /*
1225  * security layer API
1226  */
1227 
1228 /*
1229  * encode a block of data for transmission using security layer,
1230  *  returning the input buffer if there is no security layer.
1231  *  output is only valid until next call to sasl_encode or sasl_encodev
1232  * returns:
1233  *  SASL_OK      -- success (returns input if no layer negotiated)
1234  *  SASL_NOTDONE -- security layer negotiation not finished
1235  *  SASL_BADPARAM -- inputlen is greater than the SASL_MAXOUTBUF
1236  */
1237 LIBSASL_API int sasl_encode(sasl_conn_t *conn,
1238 			    const char *input, unsigned inputlen,
1239 			    const char **output, unsigned *outputlen);
1240 
1241 /*
1242  * encode a block of data for transmission using security layer
1243  *  output is only valid until next call to sasl_encode or sasl_encodev
1244  * returns:
1245  *  SASL_OK      -- success (returns input if no layer negotiated)
1246  *  SASL_NOTDONE -- security layer negotiation not finished
1247  *  SASL_BADPARAM -- input length is greater than the SASL_MAXOUTBUF
1248  *		     or no security layer
1249  */
1250 LIBSASL_API int sasl_encodev(sasl_conn_t *conn,
1251 			    const struct iovec *invec, unsigned numiov,
1252 			    const char **output, unsigned *outputlen);
1253 
1254 /*
1255  * decode a block of data received using security layer
1256  *  returning the input buffer if there is no security layer.
1257  *  output is only valid until next call to sasl_decode
1258  *
1259  *  if outputlen is 0 on return, than the value of output is undefined.
1260  *
1261  * returns:
1262  *  SASL_OK      -- success (returns input if no layer negotiated)
1263  *  SASL_NOTDONE -- security layer negotiation not finished
1264  *  SASL_BADMAC  -- bad message integrity check
1265  */
1266 LIBSASL_API int sasl_decode(sasl_conn_t *conn,
1267 			    const char *input, unsigned inputlen,
1268 			    const char **output, unsigned *outputlen);
1269 
1270 #ifdef	__cplusplus
1271 }
1272 #endif
1273 
1274 #endif	/* _SASL_SASL_H */
1275