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