1 /* This is a proposed C API for support of SASL
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*******************************
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
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
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
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
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
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
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
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
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
103 *************************************************
104 * IMPORTANT NOTE: server realms / username syntax
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 "@".
117 * If the server forbids the use of "@" in user names for other
118 * purposes, this simplifies security validation.
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
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)
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 */
182 /* max size of a sasl mechanism name */
183 #define SASL_MECHNAMEMAX 20
186 /* Define to have the same layout as a WSABUF */
187 #ifndef STRUCT_IOVEC_DEFINED
188 #define STRUCT_IOVEC_DEFINED 1
195 struct iovec; /* Defined in OS headers */
199 /* per-connection SASL negotiation state for client or server
201 typedef struct sasl_conn sasl_conn_t;
203 /* Plain text password structure.
204 * len is the length of the password, data is the text.
206 typedef struct sasl_secret {
208 unsigned char data[1]; /* variable sized */
211 /* random data context structure
213 typedef struct sasl_rand_s sasl_rand_t;
219 /****************************
220 * Configure Basic Services *
221 ****************************/
223 /* the following functions are used to adjust how allocation and mutexes work
224 * they must be called before all other SASL functions:
227 /* memory allocation functions which may optionally be replaced:
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 *);
234 LIBSASL_API void sasl_set_alloc(sasl_malloc_t *,
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
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 *);
256 /*****************************
257 * Security preference types *
258 *****************************/
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.
264 * 1 = integrity protection only
265 * 40 = 40-bit DES or 40-bit RC2/RC4
268 * 128 = 128-bit RC2/RC4/BLOWFISH
271 typedef unsigned sasl_ssf_t;
273 /* usage flags provided to sasl_server_new and sasl_client_new:
275 #define SASL_SUCCESS_DATA 0x0004 /* server supports data on success */
276 #define SASL_NEED_PROXY 0x0008 /* require a mech that allows proxying */
278 /***************************
279 * Security Property Types *
280 ***************************/
282 /* Structure specifying the client or server's security policy
283 * and optional additional properties.
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
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
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
312 typedef struct sasl_security_properties
314 /* security strength factor
315 * min_ssf = minimum acceptable final level
316 * max_ssf = maximum acceptable final level
321 /* Maximum security layer receive buffer size.
322 * 0=security layer not supported
326 /* bitfield for attacks to protect against */
327 unsigned security_flags;
329 /* NULL terminated array of additional property names, values */
330 const char **property_names;
331 const char **property_values;
332 } sasl_security_properties_t;
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
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.
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.
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.
356 int (*proc)(); /* Callback function. Types of arguments vary by 'id' */
360 /* callback ids & functions:
362 #define SASL_CB_LIST_END 0 /* end of list */
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.
370 * context -- option context from callback record
371 * plugin_name -- name of plugin (NULL = general SASL option)
372 * option -- name of option
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)
378 * SASL_OK -- no error
381 typedef int sasl_getopt_t(void *context, const char *plugin_name,
383 const char **result, unsigned *len);
384 #define SASL_CB_GETOPT 1
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
397 /* logging callback -- this allows plugins and the middleware to
398 * log operations they perform.
400 * context -- logging context from the callback record
401 * level -- logging level; see above
402 * message -- message to log
404 * SASL_OK -- no error
407 typedef int sasl_log_t(void *context,
409 const char *message);
410 #define SASL_CB_LOG 2
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).
416 * context -- getpath context from the callback record
418 * path -- colon seperated path
420 * SASL_OK -- no error
423 typedef int sasl_getpath_t(void *context,
426 #define SASL_CB_GETPATH 3
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.
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)
438 * SASL_OK -- no error (file can safely be used)
439 * SASL_CONTINUE -- continue WITHOUT using this file
443 /* these are the types of files libsasl will ask about */
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;
451 typedef int sasl_verifyfile_t(void *context,
452 const char *file, sasl_verify_type_t type);
453 #define SASL_CB_VERIFYFILE 4
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).
459 * context -- getconfpath context from the callback record
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()
466 * SASL_OK -- no error
469 typedef int sasl_getconfpath_t(void *context,
472 #define SASL_CB_GETCONFPATH 5
474 /* client/user interaction callbacks:
476 /* Simple prompt -- result must persist until next call to getsimple on
477 * same connection or until connection context is disposed
479 * context -- context from callback structure
482 * result -- set to NUL terminated string
484 * len -- length of result
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 */
498 /* get a sasl_secret_t (plaintext password with length)
500 * conn -- connection context
501 * context -- context from callback structure
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.
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 */
515 /* prompt for input in response to a challenge.
517 * context -- context from callback structure
519 * challenge -- server challenge
521 * result -- NUL terminated result, NULL = user cancel
522 * len -- length of result
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 */
532 /* prompt (or autoselect) the realm to do authentication in.
533 * may get a list of valid realms.
535 * context -- context from callback structure
537 * availrealms -- available realms; string list; NULL terminated
540 * result -- NUL terminated realm; NULL is equivalent to ""
542 * result must persist until the next callback
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 */
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
565 typedef int sasl_authorize_t(sasl_conn_t *conn,
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
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.
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
586 typedef int sasl_server_userdb_checkpass_t(sasl_conn_t *conn,
591 struct propctx *propctx);
592 #define SASL_CB_SERVER_USERDB_CHECKPASS (0x8005)
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)
601 typedef int sasl_server_userdb_setpass_t(sasl_conn_t *conn,
606 struct propctx *propctx,
608 #define SASL_CB_SERVER_USERDB_SETPASS (0x8006)
610 /* callback for a server-supplied user canonicalization function.
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.
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
627 * SASL_BADPROT username contains invalid character
630 /* User Canonicalization Function Flags */
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
637 typedef int sasl_canon_user_t(sasl_conn_t *conn,
639 const char *in, unsigned inlen,
641 const char *user_realm,
643 unsigned out_max, unsigned *out_len);
645 #define SASL_CB_CANON_USER (0x8007)
647 /**********************************
648 * Common Client/server functions *
649 **********************************/
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
655 /* a simpler way to set plugin path or configuration file path
656 * without the need to set sasl_getpath_t callback.
658 * This function can be called before sasl_server_init/sasl_client_init.
660 LIBSASL_API int sasl_set_path (int path_type, char * path);
662 /* get sasl library version information
663 * implementation is a vendor-defined string
664 * version is a vender-defined representation of the version #.
666 * This function is being deprecated in favor of sasl_version_info. */
667 LIBSASL_API void sasl_version(const char **implementation,
670 /* Extended version of sasl_version().
672 * This function is to be used
673 * for library version display and logging
674 * for bug workarounds in old library versions
676 * The sasl_version_info is not to be used for API feature detection.
678 * All parameters are optional. If NULL is specified, the value is not returned.
680 LIBSASL_API void sasl_version_info (const char **implementation,
681 const char **version_string,
687 /* dispose of all SASL plugins. Connection
688 * states have to be disposed of before calling this.
690 LIBSASL_API void sasl_done(void);
692 /* dispose connection state, sets it to NULL
693 * checks for pointer to NULL
695 LIBSASL_API void sasl_dispose(sasl_conn_t **pconn);
697 /* translate an error number into a string
699 * saslerr -- the error number
700 * langlist -- comma separated list of RFC 1766 languages (may be NULL)
702 * outlang -- the language actually used (may be NULL if don't care)
704 * the error message in UTF-8 (only the US-ASCII subset if langlist is NULL)
706 LIBSASL_API const char *sasl_errstring(int saslerr,
707 const char *langlist,
708 const char **outlang);
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)
714 * conn -- mandatory connection context
716 * the error message in UTF-8 (only the US-ASCII subset permitted if no
717 * SASL_CB_LANGUAGE callback is present)
719 LIBSASL_API const char *sasl_errdetail(sasl_conn_t *conn);
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
725 * primarily for use by server callbacks such as the sasl_authorize_t
726 * callback and internally to plug-ins
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.
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.
735 * if conn is NULL, function does nothing
737 LIBSASL_API void sasl_seterror(sasl_conn_t *conn, unsigned flags,
738 const char *fmt, ...);
739 #define SASL_NOLOG 0x01
741 /* get property from SASL connection state
742 * propnum -- property number
743 * pvalue -- pointer to value
745 * SASL_OK -- no error
746 * SASL_NOTDONE -- property not available yet
747 * SASL_BADPARAM -- bad property number
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
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 */
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.
768 #define SASL_PLUGERR 10
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
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 */
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
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.
795 #define SASL_GSS_PEER_NAME 19
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
801 /* Channel binding information. Memory is managed by the caller. */
802 typedef struct sasl_channel_binding {
806 const unsigned char *data;
807 } sasl_channel_binding_t;
809 #define SASL_CHANNEL_BINDING 21
811 /* set property in SASL connection state
813 * SASL_OK -- value set
814 * SASL_BADPARAM -- invalid property or value
816 LIBSASL_API int sasl_setprop(sasl_conn_t *conn,
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 *) */
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.
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
833 LIBSASL_API int sasl_idle(sasl_conn_t *conn);
839 /* list of client interactions with user for caller to fill in
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 */
850 /* initialize the SASL client drivers
851 * callbacks -- base callbacks for all client connections;
852 * must include getopt callback
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
861 LIBSASL_API int sasl_client_init(const sasl_callback_t *callbacks);
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)
876 * pconn -- connection negotiation structure
877 * pointer to NULL => allocate new
881 * SASL_NOMECH -- no mechanism meets requested properties
882 * SASL_NOMEM -- not enough memory
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,
890 sasl_conn_t **pconn);
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
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)
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
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,
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
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
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
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);
941 /* initialize server drivers, done once per process
942 * callbacks -- callbacks for all server connections; must include
944 * appname -- name of calling application (for lower level logging)
946 * state -- server state
949 * SASL_BADPARAM -- error in config file
950 * SASL_NOMEM -- memory failure
951 * SASL_BADVERS -- Mechanism version mismatch
953 LIBSASL_API int sasl_server_init(const sasl_callback_t *callbacks,
954 const char *appname);
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
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
965 * A buffer of size 52 is adequate for the longest format with NUL terminator.
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)
981 * pconn -- new connection context
985 * SASL_NOMEM -- not enough memory
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,
994 sasl_conn_t **pconn);
996 /* Return an array of NUL-terminated strings, terminated by a NULL pointer,
997 * which lists all possible mechanisms that the library can supply
999 * Returns NULL on failure. */
1000 LIBSASL_API const char ** sasl_global_listmech(void);
1002 /* This returns a list of mechanisms in a NUL-terminated string
1003 * conn -- the connection to list mechanisms for (either client
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
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
1017 * SASL_OK -- success
1018 * SASL_NOMEM -- not enough memory
1019 * SASL_NOMECH -- no enabled mechanisms
1021 LIBSASL_API int sasl_listmech(sasl_conn_t *conn,
1026 const char **result,
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
1038 * pconn -- the connection negotiation state on success
1040 * Same returns as sasl_server_step() or
1041 * SASL_NOMECH if mechanism not available.
1043 LIBSASL_API int sasl_server_start(sasl_conn_t *conn,
1045 const char *clientin,
1046 unsigned clientinlen,
1047 const char **serverout,
1048 unsigned *serveroutlen);
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)
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
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);
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
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)
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
1089 LIBSASL_API int sasl_checkapop(sasl_conn_t *conn,
1090 const char *challenge, unsigned challen,
1091 const char *response, unsigned resplen);
1093 /* check if a plaintext password is valid
1094 * if user is NULL, check if plaintext passwords are enabled
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)
1101 * SASL_OK -- success
1102 * SASL_NOMECH -- mechanism not supported
1103 * SASL_NOVERIFY -- user found, but no verifier
1104 * SASL_NOUSER -- user not found
1106 LIBSASL_API int sasl_checkpass(sasl_conn_t *conn,
1107 const char *user, unsigned userlen,
1108 const char *pass, unsigned passlen);
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
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
1123 LIBSASL_API int sasl_user_exists(sasl_conn_t *conn,
1124 const char *service,
1125 const char *user_realm,
1128 /* set the password for a user
1129 * conn -- SASL connection
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
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
1149 LIBSASL_API int sasl_setpass(sasl_conn_t *conn,
1151 const char *pass, unsigned passlen,
1152 const char *oldpass, unsigned oldpasslen,
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 */
1160 /*********************************************************
1161 * Auxiliary Property Support -- added by cjn 1999-09-29 *
1162 *********************************************************/
1164 #define SASL_AUX_END NULL /* last auxiliary property */
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 */
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"
1184 /* Request a set of auxiliary properties
1185 * conn connection context
1186 * propnames list of auxiliary property names to request ending with
1189 * Subsequent calls will add items to the request list. Call with NULL
1190 * to clear the request list.
1193 * SASL_OK -- success
1194 * SASL_BADPARAM -- bad count/conn parameter
1195 * SASL_NOMEM -- out of memory
1197 LIBSASL_API int sasl_auxprop_request(sasl_conn_t *conn,
1198 const char **propnames);
1200 /* Returns current auxiliary property context.
1201 * Use functions in prop.h to access content
1203 * if authentication hasn't completed, property values may be empty/NULL
1205 * properties not recognized by active plug-ins will be left empty/NULL
1207 * returns NULL if conn is invalid.
1209 LIBSASL_API struct propctx *sasl_auxprop_getctx(sasl_conn_t *conn);
1211 /* Store the set of auxiliary properties for the given user.
1212 * Use functions in prop.h to set the content.
1214 * conn connection context
1215 * ctx property context from prop_new()/prop_request()/prop_set()
1216 * user NUL terminated user
1218 * Call with NULL 'ctx' to see if the backend allows storing properties.
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
1227 LIBSASL_API int sasl_auxprop_store(sasl_conn_t *conn,
1228 struct propctx *ctx, const char *user);
1230 /**********************
1231 * security layer API *
1232 **********************/
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
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
1242 LIBSASL_API int sasl_encode(sasl_conn_t *conn,
1243 const char *input, unsigned inputlen,
1244 const char **output, unsigned *outputlen);
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
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
1254 LIBSASL_API int sasl_encodev(sasl_conn_t *conn,
1255 const struct iovec *invec, unsigned numiov,
1256 const char **output, unsigned *outputlen);
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
1262 * if outputlen is 0 on return, than the value of output is undefined.
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
1269 LIBSASL_API int sasl_decode(sasl_conn_t *conn,
1270 const char *input, unsigned inputlen,
1271 const char **output, unsigned *outputlen);