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