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