Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-02-21 10:15:32

0001 /* This is a proposed C API for support of SASL
0002  *
0003  *********************************IMPORTANT*******************************
0004  * send email to chris.newman@innosoft.com and cyrus-bugs@andrew.cmu.edu *
0005  * if you need to add new error codes, callback types, property values,  *
0006  * etc.   It is important to keep the multiple implementations of this   *
0007  * API from diverging.                                                   *
0008  *********************************IMPORTANT*******************************
0009  *
0010  * Basic Type Summary:
0011  *  sasl_conn_t       Context for a SASL connection negotiation
0012  *  sasl_ssf_t        Security layer Strength Factor
0013  *  sasl_callback_t   A typed client/server callback function and context
0014  *  sasl_interact_t   A client interaction descriptor
0015  *  sasl_secret_t     A client password
0016  *  sasl_rand_t       Random data context structure
0017  *  sasl_security_properties_t  An application's required security level
0018  *
0019  * Callbacks:
0020  *  sasl_getopt_t     client/server: Get an option value
0021  *  sasl_logmsg_t     client/server: Log message handler
0022  *  sasl_getsimple_t  client: Get user/language list
0023  *  sasl_getsecret_t  client: Get authentication secret
0024  *  sasl_chalprompt_t client: Display challenge and prompt for response
0025  *
0026  * Server only Callbacks:
0027  *  sasl_authorize_t             user authorization policy callback
0028  *  sasl_getconfpath_t           get path to search for config file
0029  *  sasl_server_userdb_checkpass check password and auxprops in userdb
0030  *  sasl_server_userdb_setpass   set password in userdb
0031  *  sasl_server_canon_user       canonicalize username routine
0032  *
0033  * Client/Server Function Summary:
0034  *  sasl_done         Release all SASL global state
0035  *  sasl_dispose      Connection done: Dispose of sasl_conn_t
0036  *  sasl_getprop      Get property (e.g., user name, security layer info)
0037  *  sasl_setprop      Set property (e.g., external ssf)
0038  *  sasl_errdetail    Generate string from last error on connection
0039  *  sasl_errstring    Translate sasl error code to a string
0040  *  sasl_encode       Encode data to send using security layer
0041  *  sasl_decode       Decode data received using security layer
0042  *  
0043  * Utility functions:
0044  *  sasl_encode64     Encode data to send using MIME base64 encoding
0045  *  sasl_decode64     Decode data received using MIME base64 encoding
0046  *  sasl_erasebuffer  Erase a buffer
0047  *
0048  * Client Function Summary:
0049  *  sasl_client_init  Load and initialize client plug-ins (call once)
0050  *  sasl_client_new   Initialize client connection context: sasl_conn_t
0051  *  sasl_client_start Select mechanism for connection
0052  *  sasl_client_step  Perform one authentication step
0053  *
0054  * Server Function Summary
0055  *  sasl_server_init  Load and initialize server plug-ins (call once)
0056  *  sasl_server_new   Initialize server connection context: sasl_conn_t
0057  *  sasl_listmech     Create list of available mechanisms
0058  *  sasl_server_start Begin an authentication exchange
0059  *  sasl_server_step  Perform one authentication exchange step
0060  *  sasl_checkpass    Check a plaintext passphrase
0061  *  sasl_checkapop    Check an APOP challenge/response (uses pseudo "APOP"
0062  *                    mechanism similar to CRAM-MD5 mechanism; optional)
0063  *  sasl_user_exists  Check if user exists
0064  *  sasl_setpass      Change a password or add a user entry
0065  *  sasl_auxprop_request  Request auxiliary properties
0066  *  sasl_auxprop_getctx   Get auxiliary property context for connection
0067  *  sasl_auxprop_store    Store a set of auxiliary properties
0068  *
0069  * Basic client model:
0070  *  1. client calls sasl_client_init() at startup to load plug-ins
0071  *  2. when connection formed, call sasl_client_new()
0072  *  3. once list of supported mechanisms received from server, client
0073  *     calls sasl_client_start().  goto 4a
0074  *  4. client calls sasl_client_step()
0075  * [4a. If SASL_INTERACT, fill in prompts and goto 4
0076  *      -- doesn't happen if callbacks provided]
0077  *  4b. If SASL error, goto 7 or 3
0078  *  4c. If SASL_OK, continue or goto 6 if last server response was success
0079  *  5. send message to server, wait for response
0080  *  5a. On data or success with server response, goto 4
0081  *  5b. On failure goto 7 or 3
0082  *  5c. On success with no server response continue
0083  *  6. continue with application protocol until connection closes
0084  *     call sasl_getprop/sasl_encode/sasl_decode() if using security layer
0085  *  7. call sasl_dispose(), may return to step 2
0086  *  8. call sasl_done() when program terminates
0087  *
0088  * Basic Server model:
0089  *  1. call sasl_server_init() at startup to load plug-ins
0090  *  2. On connection, call sasl_server_new()
0091  *  3. call sasl_listmech() and send list to client]
0092  *  4. after client AUTH command, call sasl_server_start(), goto 5a
0093  *  5. call sasl_server_step()
0094  *  5a. If SASL_CONTINUE, output to client, wait response, repeat 5
0095  *  5b. If SASL error, then goto 7
0096  *  5c. If SASL_OK, move on
0097  *  6. continue with application protocol until connection closes
0098  *     call sasl_getprop to get username
0099  *     call sasl_getprop/sasl_encode/sasl_decode() if using security layer
0100  *  7. call sasl_dispose(), may return to step 2
0101  *  8. call sasl_done() when program terminates
0102  *
0103  *************************************************
0104  * IMPORTANT NOTE: server realms / username syntax
0105  *
0106  * If a user name contains a "@", then the rightmost "@" in the user name
0107  * separates the account name from the realm in which this account is
0108  * located.  A single server may support multiple realms.  If the
0109  * server knows the realm at connection creation time (e.g., a server
0110  * with multiple IP addresses tightly binds one address to a specific
0111  * realm) then that realm must be passed in the user_realm field of
0112  * the sasl_server_new call.  If user_realm is non-empty and an
0113  * unqualified user name is supplied, then the canon_user facility is
0114  * expected to append "@" and user_realm to the user name.  The canon_user
0115  * facility may treat other characters such as "%" as equivalent to "@".
0116  *
0117  * If the server forbids the use of "@" in user names for other
0118  * purposes, this simplifies security validation.
0119  */
0120 
0121 #ifndef SASL_H
0122 #define SASL_H 1
0123 
0124 #include <stddef.h>  /* For size_t */
0125 
0126 /* Keep in sync with win32/common.mak */
0127 #define SASL_VERSION_MAJOR 2
0128 #define SASL_VERSION_MINOR 1
0129 #define SASL_VERSION_STEP 28
0130 
0131 /* A convenience macro: same as was defined in the OpenLDAP LDAPDB */
0132 #define SASL_VERSION_FULL ((SASL_VERSION_MAJOR << 16) |\
0133       (SASL_VERSION_MINOR << 8) | SASL_VERSION_STEP)
0134 
0135 #include "prop.h"
0136 
0137 /*************
0138  * Basic API *
0139  *************/
0140 
0141 /* SASL result codes: */
0142 #define SASL_CONTINUE    1   /* another step is needed in authentication */
0143 #define SASL_OK          0   /* successful result */
0144 #define SASL_FAIL       -1   /* generic failure */
0145 #define SASL_NOMEM      -2   /* memory shortage failure */
0146 #define SASL_BUFOVER    -3   /* overflowed buffer */
0147 #define SASL_NOMECH     -4   /* mechanism not supported */
0148 #define SASL_BADPROT    -5   /* bad protocol / cancel */
0149 #define SASL_NOTDONE    -6   /* can't request info until later in exchange */
0150 #define SASL_BADPARAM   -7   /* invalid parameter supplied */
0151 #define SASL_TRYAGAIN   -8   /* transient failure (e.g., weak key) */
0152 #define SASL_BADMAC -9   /* integrity check failed */
0153 #define SASL_NOTINIT    -12  /* SASL library not initialized */
0154                              /* -- client only codes -- */
0155 #define SASL_INTERACT    2   /* needs user interaction */
0156 #define SASL_BADSERV    -10  /* server failed mutual authentication step */
0157 #define SASL_WRONGMECH  -11  /* mechanism doesn't support requested feature */
0158                              /* -- server only codes -- */
0159 #define SASL_BADAUTH    -13  /* authentication failure */
0160 #define SASL_NOAUTHZ    -14  /* authorization failure */
0161 #define SASL_TOOWEAK    -15  /* mechanism too weak for this user */
0162 #define SASL_ENCRYPT    -16  /* encryption needed to use mechanism */
0163 #define SASL_TRANS      -17  /* One time use of a plaintext password will
0164                 enable requested mechanism for user */
0165 #define SASL_EXPIRED    -18  /* passphrase expired, has to be reset */
0166 #define SASL_DISABLED   -19  /* account disabled */
0167 #define SASL_NOUSER     -20  /* user not found */
0168 #define SASL_BADVERS    -23  /* version mismatch with plug-in */
0169 #define SASL_UNAVAIL    -24  /* remote authentication server unavailable */
0170 #define SASL_NOVERIFY   -26  /* user exists, but no verifier for user */
0171                  /* -- codes for password setting -- */
0172 #define SASL_PWLOCK     -21  /* passphrase locked */
0173 #define SASL_NOCHANGE   -22  /* requested change was not needed */
0174 #define SASL_WEAKPASS   -27  /* passphrase is too weak for security policy */
0175 #define SASL_NOUSERPASS -28  /* user supplied passwords not permitted */
0176 #define SASL_NEED_OLD_PASSWD -29 /* sasl_setpass needs old password in order
0177                     to perform password change */
0178 #define SASL_CONSTRAINT_VIOLAT  -30 /* a property can't be stored,
0179                        because of some constrains/policy violation */
0180 
0181 #define SASL_BADBINDING -32  /* channel binding failure */
0182 #define SASL_CONFIGERR  -100 /* error when parsing configuration file */
0183 
0184 /* max size of a sasl mechanism name */
0185 #define SASL_MECHNAMEMAX 20
0186 
0187 #ifdef _WIN32
0188 /* Define to have the same layout as a WSABUF */
0189 #ifndef STRUCT_IOVEC_DEFINED
0190 #define STRUCT_IOVEC_DEFINED 1
0191 struct iovec {
0192     long iov_len;
0193     char *iov_base;
0194 };
0195 #endif
0196 #else
0197 struct iovec;                    /* Defined in OS headers */
0198 #endif
0199 
0200 
0201 /* per-connection SASL negotiation state for client or server
0202  */
0203 typedef struct sasl_conn sasl_conn_t;
0204 
0205 /* Plain text password structure.
0206  *  len is the length of the password, data is the text.
0207  */
0208 typedef struct sasl_secret {
0209     unsigned long len;
0210     unsigned char data[1];      /* variable sized */
0211 } sasl_secret_t;
0212 
0213 /* random data context structure
0214  */
0215 typedef struct sasl_rand_s sasl_rand_t;
0216 
0217 #ifdef __cplusplus
0218 extern "C" {
0219 #endif
0220 
0221 /****************************
0222  * Configure Basic Services *
0223  ****************************/
0224 
0225 /* the following functions are used to adjust how allocation and mutexes work
0226  * they must be called before all other SASL functions:
0227  */
0228 
0229 #include <sys/types.h>
0230 
0231 /* memory allocation functions which may optionally be replaced:
0232  */
0233 typedef void *sasl_malloc_t(size_t);
0234 typedef void *sasl_calloc_t(size_t, size_t);
0235 typedef void *sasl_realloc_t(void *, size_t);
0236 typedef void sasl_free_t(void *);
0237 
0238 LIBSASL_API void sasl_set_alloc(sasl_malloc_t *,
0239                 sasl_calloc_t *,
0240                 sasl_realloc_t *,
0241                 sasl_free_t *);
0242 
0243 /* mutex functions which may optionally be replaced:
0244  *  sasl_mutex_alloc allocates a mutex structure
0245  *  sasl_mutex_lock blocks until mutex locked
0246  *   returns -1 on deadlock or parameter error
0247  *   returns 0 on success
0248  *  sasl_mutex_unlock unlocks mutex if it's locked
0249  *   returns -1 if not locked or parameter error
0250  *   returns 0 on success
0251  *  sasl_mutex_free frees a mutex structure
0252  */
0253 typedef void *sasl_mutex_alloc_t(void);
0254 typedef int sasl_mutex_lock_t(void *mutex);
0255 typedef int sasl_mutex_unlock_t(void *mutex);
0256 typedef void sasl_mutex_free_t(void *mutex);
0257 LIBSASL_API void sasl_set_mutex(sasl_mutex_alloc_t *, sasl_mutex_lock_t *,
0258                 sasl_mutex_unlock_t *, sasl_mutex_free_t *);
0259 
0260 /*****************************
0261  * Security preference types *
0262  *****************************/
0263 
0264 /* security layer strength factor -- an unsigned integer usable by the caller
0265  *  to specify approximate security layer strength desired.  Roughly
0266  *  correlated to effective key length for encryption.
0267  * 0   = no protection
0268  * 1   = integrity protection only
0269  * 40  = 40-bit DES or 40-bit RC2/RC4
0270  * 56  = DES
0271  * 112 = triple-DES
0272  * 128 = 128-bit RC2/RC4/BLOWFISH
0273  * 256 = baseline AES
0274  */
0275 typedef unsigned sasl_ssf_t;
0276 
0277 /* usage flags provided to sasl_server_new and sasl_client_new:
0278  */
0279 #define SASL_SUCCESS_DATA    0x0004 /* server supports data on success */
0280 #define SASL_NEED_PROXY      0x0008 /* require a mech that allows proxying */
0281 #define SASL_NEED_HTTP       0x0010 /* require a mech that can do HTTP auth */
0282 
0283 /***************************
0284  * Security Property Types *
0285  ***************************/
0286 
0287 /* Structure specifying the client or server's security policy
0288  * and optional additional properties.
0289  */
0290 
0291 /* These are the various security flags apps can specify. */
0292 /* NOPLAINTEXT          -- don't permit mechanisms susceptible to simple
0293  *                         passive attack (e.g., PLAIN, LOGIN)
0294  * NOACTIVE             -- protection from active (non-dictionary) attacks
0295  *                         during authentication exchange.
0296  *                         Authenticates server.
0297  * NODICTIONARY         -- don't permit mechanisms susceptible to passive
0298  *                         dictionary attack
0299  * FORWARD_SECRECY      -- require forward secrecy between sessions
0300  *                         (breaking one won't help break next)
0301  * NOANONYMOUS          -- don't permit mechanisms that allow anonymous login
0302  * PASS_CREDENTIALS     -- require mechanisms which pass client
0303  *             credentials, and allow mechanisms which can pass
0304  *             credentials to do so
0305  * MUTUAL_AUTH          -- require mechanisms which provide mutual
0306  *             authentication
0307  */
0308 #define SASL_SEC_NOPLAINTEXT      0x0001
0309 #define SASL_SEC_NOACTIVE         0x0002
0310 #define SASL_SEC_NODICTIONARY     0x0004
0311 #define SASL_SEC_FORWARD_SECRECY  0x0008
0312 #define SASL_SEC_NOANONYMOUS      0x0010
0313 #define SASL_SEC_PASS_CREDENTIALS 0x0020
0314 #define SASL_SEC_MUTUAL_AUTH      0x0040
0315 #define SASL_SEC_MAXIMUM          0xFFFF
0316 
0317 /* This is used when adding hash size to the security_flags field */
0318 /* NB: hash size is in bits */
0319 #define SASL_SET_HASH_STRENGTH_BITS(x)    (((x) / 8) << 16)
0320 
0321 /* NB: This value is in bytes */
0322 #define SASL_GET_HASH_STRENGTH(x)    ((x) >> 16)
0323 
0324 typedef struct sasl_security_properties 
0325 { 
0326     /* security strength factor
0327      *  min_ssf      = minimum acceptable final level
0328      *  max_ssf      = maximum acceptable final level
0329      */ 
0330     sasl_ssf_t min_ssf;
0331     sasl_ssf_t max_ssf;
0332 
0333     /* Maximum security layer receive buffer size.
0334      *  0=security layer not supported
0335      */
0336     unsigned maxbufsize; 
0337     
0338     /* bitfield for attacks to protect against */
0339     unsigned security_flags;
0340 
0341     /* NULL terminated array of additional property names, values */ 
0342     const char **property_names;
0343     const char **property_values;
0344 } sasl_security_properties_t; 
0345 
0346 /******************
0347  * Callback types *
0348  ******************/
0349 
0350 /*
0351  * Extensible type for a client/server callbacks
0352  *  id      -- identifies callback type
0353  *  proc    -- procedure call arguments vary based on id
0354  *  context -- context passed to procedure
0355  */
0356 /* Note that any memory that is allocated by the callback needs to be
0357  * freed by the application, be it via function call or interaction.
0358  *
0359  * It may be freed after sasl_*_step returns SASL_OK.  if the mechanism
0360  * requires this information to persist (for a security layer, for example)
0361  * it must maintain a private copy.
0362  */
0363 typedef struct sasl_callback {
0364     /* Identifies the type of the callback function.
0365      * Mechanisms must ignore callbacks with id's they don't recognize.
0366      */
0367     unsigned long id;
0368     int (*proc)(void);   /* Callback function.  Types of arguments vary by 'id' */
0369     void *context;
0370 } sasl_callback_t;
0371 
0372 /* callback ids & functions:
0373  */
0374 #define SASL_CB_LIST_END   0  /* end of list */
0375 
0376 /* option reading callback -- this allows a SASL configuration to be
0377  *  encapsulated in the caller's configuration system.  Some implementations
0378  *  may use default config file(s) if this is omitted.  Configuration items
0379  *  may be plugin-specific and are arbitrary strings.
0380  *
0381  * inputs:
0382  *  context     -- option context from callback record
0383  *  plugin_name -- name of plugin (NULL = general SASL option)
0384  *  option      -- name of option
0385  * output:
0386  *  result      -- set to result which persists until next getopt in
0387  *                 same thread, unchanged if option not found
0388  *  len         -- length of result (may be NULL)
0389  * returns:
0390  *  SASL_OK     -- no error
0391  *  SASL_FAIL   -- error
0392  */
0393 typedef int sasl_getopt_t(void *context, const char *plugin_name,
0394               const char *option,
0395               const char **result, unsigned *len);
0396 #define SASL_CB_GETOPT       1
0397 
0398 /* Logging levels for use with the logging callback function. */
0399 #define SASL_LOG_NONE  0    /* don't log anything */
0400 #define SASL_LOG_ERR   1    /* log unusual errors (default) */
0401 #define SASL_LOG_FAIL  2    /* log all authentication failures */
0402 #define SASL_LOG_WARN  3    /* log non-fatal warnings */
0403 #define SASL_LOG_NOTE  4    /* more verbose than LOG_WARN */
0404 #define SASL_LOG_DEBUG 5    /* more verbose than LOG_NOTE */
0405 #define SASL_LOG_TRACE 6    /* traces of internal protocols */
0406 #define SASL_LOG_PASS  7    /* traces of internal protocols, including
0407                  * passwords */
0408 
0409 /* logging callback -- this allows plugins and the middleware to
0410  *  log operations they perform.
0411  * inputs:
0412  *  context     -- logging context from the callback record
0413  *  level       -- logging level; see above
0414  *  message     -- message to log
0415  * returns:
0416  *  SASL_OK     -- no error
0417  *  SASL_FAIL   -- error
0418  */
0419 typedef int sasl_log_t(void *context,
0420                int level,
0421                const char *message);
0422 #define SASL_CB_LOG     2
0423 
0424 /* getpath callback -- this allows applications to specify the
0425  * colon-separated path to search for plugins (by default,
0426  * taken from an implementation-specific location).
0427  * inputs:
0428  *  context     -- getpath context from the callback record
0429  * outputs:
0430  *  path    -- colon seperated path
0431  * returns:
0432  *  SASL_OK     -- no error
0433  *  SASL_FAIL   -- error
0434  */
0435 typedef int sasl_getpath_t(void *context,
0436                const char **path);
0437 
0438 #define SASL_CB_GETPATH     3
0439 
0440 /* verify file callback -- this allows applications to check if they
0441  * want SASL to use files, file by file.  This is intended to allow
0442  * applications to sanity check the environment to make sure plugins
0443  * or the configuration file can't be written to, etc.
0444  * inputs: 
0445  *  context     -- verifypath context from the callback record
0446  *  file        -- full path to file to verify
0447  *  type        -- type of file to verify (see below)
0448 
0449  * returns:
0450  *  SASL_OK        -- no error (file can safely be used)
0451  *  SASL_CONTINUE  -- continue WITHOUT using this file
0452  *  SASL_FAIL      -- error 
0453  */
0454 
0455 /* these are the types of files libsasl will ask about */
0456 typedef enum {
0457     SASL_VRFY_PLUGIN=0,     /* a DLL/shared library plug-in */
0458     SASL_VRFY_CONF=1,       /* a configuration file */
0459     SASL_VRFY_PASSWD=2,     /* a password storage file/db */
0460     SASL_VRFY_OTHER=3       /* some other file */
0461 } sasl_verify_type_t;
0462 
0463 typedef int sasl_verifyfile_t(void *context,
0464                               const char *file, sasl_verify_type_t type);
0465 #define SASL_CB_VERIFYFILE  4
0466 
0467 /* getconfpath callback -- this allows applications to specify the
0468  * colon-separated path to search for config files (by default,
0469  * taken from the SASL_CONF_PATH environment variable).
0470  * inputs:
0471  *  context     -- getconfpath context from the callback record
0472  * outputs:
0473  *  path        -- colon seperated path (allocated on the heap; the
0474  *                 library will free it using the sasl_free_t *
0475  *                 passed to sasl_set_callback, or the standard free()
0476  *                 library call).
0477  * returns:
0478  *  SASL_OK     -- no error
0479  *  SASL_FAIL   -- error
0480  */
0481 typedef int sasl_getconfpath_t(void *context,
0482                                char **path);
0483 
0484 #define SASL_CB_GETCONFPATH  5
0485 
0486 /* client/user interaction callbacks:
0487  */
0488 /* Simple prompt -- result must persist until next call to getsimple on
0489  *  same connection or until connection context is disposed
0490  * inputs:
0491  *  context       -- context from callback structure
0492  *  id            -- callback id
0493  * outputs:
0494  *  result        -- set to NUL terminated string
0495  *                   NULL = user cancel
0496  *  len           -- length of result
0497  * returns SASL_OK
0498  */
0499 typedef int sasl_getsimple_t(void *context, int id,
0500                  const char **result, unsigned *len);
0501 #define SASL_CB_USER         0x4001  /* client user identity to login as */
0502 #define SASL_CB_AUTHNAME     0x4002  /* client authentication name */
0503 #define SASL_CB_LANGUAGE     0x4003  /* comma separated list of RFC 1766
0504                           * language codes in order of preference
0505                       * to be used to localize client prompts
0506                       * or server error codes */
0507 #define SASL_CB_CNONCE       0x4007  /* caller supplies client-nonce
0508                       * primarily for testing purposes */
0509 
0510 /* get a sasl_secret_t (plaintext password with length)
0511  * inputs:
0512  *  conn          -- connection context
0513  *  context       -- context from callback structure
0514  *  id            -- callback id
0515  * outputs:
0516  *  psecret       -- set to NULL to cancel
0517  *                   set to password structure which must persist until
0518  *                   next call to getsecret in same connection, but middleware
0519  *                   will erase password data when it's done with it.
0520  * returns SASL_OK
0521  */
0522 typedef int sasl_getsecret_t(sasl_conn_t *conn, void *context, int id,
0523                  sasl_secret_t **psecret);
0524 #define SASL_CB_PASS         0x4004  /* client passphrase-based secret */
0525 
0526 
0527 /* prompt for input in response to a challenge.
0528  * input:
0529  *  context   -- context from callback structure
0530  *  id        -- callback id
0531  *  challenge -- server challenge
0532  * output:
0533  *  result    -- NUL terminated result, NULL = user cancel
0534  *  len       -- length of result
0535  * returns SASL_OK
0536  */
0537 typedef int sasl_chalprompt_t(void *context, int id,
0538                   const char *challenge,
0539                   const char *prompt, const char *defresult,
0540                   const char **result, unsigned *len);
0541 #define SASL_CB_ECHOPROMPT   0x4005 /* challenge and client enterred result */
0542 #define SASL_CB_NOECHOPROMPT 0x4006 /* challenge and client enterred result */
0543 
0544 /* prompt (or autoselect) the realm to do authentication in.
0545  *  may get a list of valid realms.
0546  * input:
0547  *  context     -- context from callback structure
0548  *  id          -- callback id
0549  *  availrealms -- available realms; string list; NULL terminated
0550  *                 list may be empty.
0551  * output:
0552  *  result      -- NUL terminated realm; NULL is equivalent to ""
0553  * returns SASL_OK
0554  * result must persist until the next callback
0555  */
0556 typedef int sasl_getrealm_t(void *context, int id,
0557                 const char **availrealms,
0558                 const char **result);
0559 #define SASL_CB_GETREALM (0x4008) /* realm to attempt authentication in */
0560 
0561 /* server callbacks:
0562  */
0563 
0564 /* improved callback to verify authorization;
0565  *     canonicalization now handled elsewhere
0566  *  conn           -- connection context
0567  *  requested_user -- the identity/username to authorize (NUL terminated)
0568  *  rlen           -- length of requested_user
0569  *  auth_identity  -- the identity associated with the secret (NUL terminated)
0570  *  alen           -- length of auth_identity
0571  *  default_realm  -- default user realm, as passed to sasl_server_new if
0572  *  urlen          -- length of default realm
0573  *  propctx        -- auxiliary properties
0574  * returns SASL_OK on success,
0575  *         SASL_NOAUTHZ or other SASL response on failure
0576  */
0577 typedef int sasl_authorize_t(sasl_conn_t *conn,
0578                  void *context,
0579                  const char *requested_user, unsigned rlen,
0580                  const char *auth_identity, unsigned alen,
0581                  const char *def_realm, unsigned urlen,
0582                  struct propctx *propctx);
0583 #define SASL_CB_PROXY_POLICY 0x8001
0584 
0585 /* functions for "userdb" based plugins to call to get/set passwords.
0586  * the location for the passwords is determined by the caller or middleware.
0587  * plug-ins may get passwords from other locations.
0588  */
0589 
0590 /* callback to verify a plaintext password against the caller-supplied
0591  * user database.  This is necessary to allow additional <method>s for
0592  * encoding of the userPassword property.
0593  *  user          -- NUL terminated user name with user@realm syntax
0594  *  pass          -- password to check (may not be NUL terminated)
0595  *  passlen       -- length of password to check
0596  *  propctx       -- auxiliary properties for user
0597  */
0598 typedef int sasl_server_userdb_checkpass_t(sasl_conn_t *conn,
0599                        void *context,
0600                        const char *user,
0601                        const char *pass,
0602                        unsigned passlen,
0603                        struct propctx *propctx);
0604 #define SASL_CB_SERVER_USERDB_CHECKPASS (0x8005)
0605 
0606 /* callback to store/change a plaintext password in the user database
0607  *  user          -- NUL terminated user name with user@realm syntax
0608  *  pass          -- password to store (may not be NUL terminated)
0609  *  passlen       -- length of password to store
0610  *  propctx       -- auxiliary properties (not stored)
0611  *  flags         -- see SASL_SET_* flags below (SASL_SET_CREATE optional)
0612  */
0613 typedef int sasl_server_userdb_setpass_t(sasl_conn_t *conn,
0614                      void *context,
0615                      const char *user,
0616                      const char *pass,
0617                      unsigned passlen,
0618                      struct propctx *propctx,
0619                      unsigned flags);
0620 #define SASL_CB_SERVER_USERDB_SETPASS (0x8006)
0621 
0622 /* callback for a server-supplied user canonicalization function.
0623  *
0624  * This function is called directly after the mechanism has the
0625  * authentication and authorization IDs.  It is called before any
0626  * User Canonicalization plugin is called.  It has the responsibility
0627  * of copying its output into the provided output buffers.
0628  * 
0629  *  in, inlen     -- user name to canonicalize, may not be NUL terminated
0630  *                   may be same buffer as out
0631  *  flags         -- not currently used, supplied by auth mechanism
0632  *  user_realm    -- the user realm (may be NULL in case of client)
0633  *  out           -- buffer to copy user name
0634  *  out_max       -- max length of user name
0635  *  out_len       -- set to length of user name
0636  *
0637  * returns
0638  *  SASL_OK         on success
0639  *  SASL_BADPROT    username contains invalid character
0640  */
0641 
0642 /* User Canonicalization Function Flags */
0643 
0644 #define SASL_CU_NONE    0x00 /* Not a valid flag to pass */
0645 /* One of the following two is required */
0646 #define SASL_CU_AUTHID  0x01
0647 #define SASL_CU_AUTHZID 0x02
0648 
0649 /* Combine the following with SASL_CU_AUTHID, if you don't want
0650    to fail if auxprop returned SASL_NOUSER/SASL_NOMECH. */
0651 #define SASL_CU_EXTERNALLY_VERIFIED 0x04
0652 
0653 #define SASL_CU_OVERRIDE        0x08    /* mapped to SASL_AUXPROP_OVERRIDE */
0654 
0655 /* The following CU flags are passed "as is" down to auxprop lookup */
0656 #define SASL_CU_ASIS_MASK       0xFFF0
0657 /* NOTE: Keep in sync with SASL_AUXPROP_<XXX> flags */
0658 #define SASL_CU_VERIFY_AGAINST_HASH 0x10
0659 
0660 
0661 typedef int sasl_canon_user_t(sasl_conn_t *conn,
0662                   void *context,
0663                   const char *in, unsigned inlen,
0664                   unsigned flags,
0665                   const char *user_realm,
0666                   char *out,
0667                   unsigned out_max, unsigned *out_len);
0668 
0669 #define SASL_CB_CANON_USER (0x8007)
0670 
0671 /**********************************
0672  * Common Client/server functions *
0673  **********************************/
0674 
0675 /* Types of paths to set (see sasl_set_path below). */
0676 #define SASL_PATH_TYPE_PLUGIN   0
0677 #define SASL_PATH_TYPE_CONFIG   1
0678 
0679 /* a simpler way to set plugin path or configuration file path
0680  * without the need to set sasl_getpath_t callback.
0681  *
0682  * This function can be called before sasl_server_init/sasl_client_init.
0683  */  
0684 LIBSASL_API int sasl_set_path (int path_type, char * path);
0685 
0686 /* get sasl library version information
0687  * implementation is a vendor-defined string
0688  * version is a vender-defined representation of the version #.
0689  *
0690  * This function is being deprecated in favor of sasl_version_info. */
0691 LIBSASL_API void sasl_version(const char **implementation,
0692                   int *version);
0693 
0694 /* Extended version of sasl_version().
0695  *
0696  * This function is to be used
0697  *  for library version display and logging
0698  *  for bug workarounds in old library versions
0699  *
0700  * The sasl_version_info is not to be used for API feature detection.
0701  *
0702  * All parameters are optional. If NULL is specified, the value is not returned.
0703  */
0704 LIBSASL_API void sasl_version_info (const char **implementation,
0705                 const char **version_string,
0706                 int *version_major,
0707                 int *version_minor,
0708                 int *version_step,
0709                 int *version_patch);
0710 
0711 /* dispose of all SASL plugins.  Connection
0712  * states have to be disposed of before calling this.
0713  *
0714  * This function is DEPRECATED in favour of sasl_server_done/
0715  * sasl_client_done.
0716  */
0717 LIBSASL_API void sasl_done(void);
0718 
0719 /* dispose of all SASL plugins.  Connection
0720  * states have to be disposed of before calling this.
0721  * This function should be called instead of sasl_done(),
0722    whenever possible.
0723  */
0724 LIBSASL_API int sasl_server_done(void);
0725 
0726 /* dispose of all SASL plugins.  Connection
0727  * states have to be disposed of before calling this.
0728  * This function should be called instead of sasl_done(),
0729    whenever possible.
0730  */
0731 LIBSASL_API int sasl_client_done(void);
0732 
0733 /* dispose connection state, sets it to NULL
0734  *  checks for pointer to NULL
0735  */
0736 LIBSASL_API void sasl_dispose(sasl_conn_t **pconn);
0737 
0738 /* translate an error number into a string
0739  * input:
0740  *  saslerr  -- the error number
0741  *  langlist -- comma separated list of RFC 1766 languages (may be NULL)
0742  * results:
0743  *  outlang  -- the language actually used (may be NULL if don't care)
0744  * returns:
0745  *  the error message in UTF-8 (only the US-ASCII subset if langlist is NULL)
0746  */
0747 LIBSASL_API const char *sasl_errstring(int saslerr,
0748                        const char *langlist,
0749                        const char **outlang);
0750 
0751 /* get detail about the last error that occurred on a connection
0752  * text is sanitized so it's suitable to send over the wire
0753  * (e.g., no distinction between SASL_BADAUTH and SASL_NOUSER)
0754  * input:
0755  *  conn          -- mandatory connection context
0756  * returns:
0757  *  the error message in UTF-8 (only the US-ASCII subset permitted if no
0758  *  SASL_CB_LANGUAGE callback is present)
0759  */
0760 LIBSASL_API const char *sasl_errdetail(sasl_conn_t *conn);
0761 
0762 /* set the error string which will be returned by sasl_errdetail() using
0763  *  syslog()-style formatting (e.g. printf-style with %m as most recent
0764  *  errno error)
0765  *
0766  *  primarily for use by server callbacks such as the sasl_authorize_t
0767  *  callback and internally to plug-ins
0768  *
0769  * This will also trigger a call to the SASL logging callback (if any)
0770  * with a level of SASL_LOG_FAIL unless the SASL_NOLOG flag is set.
0771  *
0772  * Messages should be sensitive to the current language setting.  If there
0773  * is no SASL_CB_LANGUAGE callback messages MUST be US-ASCII otherwise UTF-8
0774  * is used and use of RFC 2482 for mixed-language text is encouraged.
0775  *
0776  * if conn is NULL, function does nothing
0777  */
0778 LIBSASL_API void sasl_seterror(sasl_conn_t *conn, unsigned flags,
0779                    const char *fmt, ...);
0780 #define SASL_NOLOG       0x01
0781                
0782 /* get property from SASL connection state
0783  *  propnum       -- property number
0784  *  pvalue        -- pointer to value
0785  * returns:
0786  *  SASL_OK       -- no error
0787  *  SASL_NOTDONE  -- property not available yet
0788  *  SASL_BADPARAM -- bad property number
0789  */
0790 LIBSASL_API int sasl_getprop(sasl_conn_t *conn, int propnum,
0791                  const void **pvalue);
0792 #define SASL_USERNAME     0 /* pointer to NUL terminated user name */
0793 #define SASL_SSF          1 /* security layer security strength factor,
0794                                  * if 0, call to sasl_encode, sasl_decode
0795                                  * unnecessary */
0796 #define SASL_MAXOUTBUF    2     /* security layer max output buf unsigned */  
0797 #define SASL_DEFUSERREALM 3 /* default realm passed to server_new */
0798                 /* or set with setprop */
0799 #define SASL_GETOPTCTX    4 /* context for getopt callback */
0800 #define SASL_CALLBACK     7 /* current callback function list */
0801 #define SASL_IPLOCALPORT  8 /* iplocalport string passed to server_new */
0802 #define SASL_IPREMOTEPORT 9 /* ipremoteport string passed to server_new */
0803 
0804 /* This returns a string which is either empty or has an error message
0805  * from sasl_seterror (e.g., from a plug-in or callback).  It differs
0806  * from the result of sasl_errdetail() which also takes into account the
0807  * last return status code.
0808  */
0809 #define SASL_PLUGERR     10
0810 
0811 /* a handle to any delegated credentials or NULL if none is present 
0812  * is returned by the mechanism. The user will probably need to know
0813  * which mechanism was used to actually known how to make use of them
0814  * currently only implemented for the gssapi mechanism */
0815 #define SASL_DELEGATEDCREDS 11
0816 
0817 #define SASL_SERVICE      12    /* service passed to sasl_*_new */
0818 #define SASL_SERVERFQDN   13    /* serverFQDN passed to sasl_*_new */
0819 #define SASL_AUTHSOURCE   14    /* name of auth source last used, useful
0820                  * for failed authentication tracking */
0821 #define SASL_MECHNAME     15    /* active mechanism name, if any */
0822 #define SASL_AUTHUSER     16    /* authentication/admin user */
0823 #define SASL_APPNAME      17    /* application name (used for logging/
0824                    configuration), same as appname parameter
0825                    to sasl_server_init */
0826 
0827 /* GSS-API credential handle for sasl_client_step() or sasl_server_step().
0828  * The application is responsible for releasing this credential handle. */
0829 #define SASL_GSS_CREDS    18
0830 
0831 /* GSS name (gss_name_t) of the peer, as output by gss_inquire_context()
0832  * or gss_accept_sec_context().
0833  * On server end this is similar to SASL_USERNAME, but the gss_name_t
0834  * structure can contain additional attributes associated with the peer.
0835  */
0836 #define SASL_GSS_PEER_NAME  19
0837 
0838 /* Local GSS name (gss_name_t) as output by gss_inquire_context(). This
0839  * is particularly useful for servers that respond to multiple names. */
0840 #define SASL_GSS_LOCAL_NAME 20
0841 
0842 /* Channel binding information. Memory is managed by the caller. */
0843 typedef struct sasl_channel_binding {
0844     const char *name;
0845     int critical;
0846     unsigned long len;
0847     const unsigned char *data;
0848 } sasl_channel_binding_t;
0849 
0850 #define SASL_CHANNEL_BINDING    21
0851 
0852 /* HTTP Request (RFC 2616) - ONLY used for HTTP Digest Auth (RFC 2617) */
0853 typedef struct sasl_http_request {
0854     const char *method;         /* HTTP Method */
0855     const char *uri;            /* request-URI */
0856     const unsigned char *entity;    /* entity-body */
0857     unsigned long elen;         /* entity-body length */
0858     unsigned non_persist;       /* Is it a non-persistent connection? */
0859 } sasl_http_request_t;
0860 
0861 #define SASL_HTTP_REQUEST   22
0862 
0863 /* set property in SASL connection state
0864  * returns:
0865  *  SASL_OK       -- value set
0866  *  SASL_BADPARAM -- invalid property or value
0867  */
0868 LIBSASL_API int sasl_setprop(sasl_conn_t *conn,
0869                  int propnum,
0870                  const void *value);
0871 #define SASL_SSF_EXTERNAL  100  /* external SSF active (sasl_ssf_t *) */
0872 #define SASL_SEC_PROPS     101  /* sasl_security_properties_t */
0873 #define SASL_AUTH_EXTERNAL 102  /* external authentication ID (const char *) */
0874 
0875 /* If the SASL_AUTH_EXTERNAL value is non-NULL, then a special version of the
0876  * EXTERNAL mechanism is enabled (one for server-embedded EXTERNAL mechanisms).
0877  * Otherwise, the EXTERNAL mechanism will be absent unless a plug-in
0878  * including EXTERNAL is present.
0879  */
0880 
0881 /* do precalculations during an idle period or network round trip
0882  *  may pass NULL to precompute for some mechanisms prior to connect
0883  *  returns 1 if action taken, 0 if no action taken
0884  */
0885 LIBSASL_API int sasl_idle(sasl_conn_t *conn);
0886 
0887 /**************
0888  * Client API *
0889  **************/
0890 
0891 /* list of client interactions with user for caller to fill in
0892  */
0893 typedef struct sasl_interact {
0894     unsigned long id;       /* same as client/user callback ID */
0895     const char *challenge;  /* presented to user (e.g. OTP challenge) */
0896     const char *prompt;     /* presented to user (e.g. "Username: ") */
0897     const char *defresult;  /* default result string */
0898     const void *result;     /* set to point to result */
0899     unsigned len;       /* set to length of result */
0900 } sasl_interact_t;
0901 
0902 /* initialize the SASL client drivers
0903  *  callbacks      -- base callbacks for all client connections;
0904  *                    must include getopt callback
0905  * returns:
0906  *  SASL_OK        -- Success
0907  *  SASL_NOMEM     -- Not enough memory
0908  *  SASL_BADVERS   -- Mechanism version mismatch
0909  *  SASL_BADPARAM  -- missing getopt callback or error in config file
0910  *  SASL_NOMECH    -- No mechanisms available
0911  *  ...
0912  */
0913 LIBSASL_API int sasl_client_init(const sasl_callback_t *callbacks);
0914 
0915 /* initialize a client exchange based on the specified mechanism
0916  *  service       -- registered name of the service using SASL (e.g. "imap")
0917  *  serverFQDN    -- the fully qualified domain name of the server
0918  *  iplocalport   -- client IPv4/IPv6 domain literal string with port
0919  *                    (if NULL, then mechanisms requiring IPaddr are disabled)
0920  *  ipremoteport  -- server IPv4/IPv6 domain literal string with port
0921  *                    (if NULL, then mechanisms requiring IPaddr are disabled)
0922  *  prompt_supp   -- list of client interactions supported
0923  *                   may also include sasl_getopt_t context & call
0924  *                   NULL prompt_supp = user/pass via SASL_INTERACT only
0925  *                   NULL proc = interaction supported via SASL_INTERACT
0926  *  flags         -- server usage flags (see above)
0927  * in/out:
0928  *  pconn         -- connection negotiation structure
0929  *                   pointer to NULL => allocate new
0930  *
0931  * Returns:
0932  *  SASL_OK       -- success
0933  *  SASL_NOMECH   -- no mechanism meets requested properties
0934  *  SASL_NOMEM    -- not enough memory
0935  */
0936 LIBSASL_API int sasl_client_new(const char *service,
0937                 const char *serverFQDN,
0938                 const char *iplocalport,
0939                 const char *ipremoteport,
0940                 const sasl_callback_t *prompt_supp,
0941                 unsigned flags,
0942                 sasl_conn_t **pconn);
0943 
0944 /* select a mechanism for a connection
0945  *  mechlist      -- mechanisms server has available (punctuation ignored)
0946  *                   if NULL, then discard cached info and retry last mech
0947  * output:
0948  *  prompt_need   -- on SASL_INTERACT, list of prompts needed to continue
0949  *                   may be NULL if callbacks provided
0950  *  clientout     -- the initial client response to send to the server
0951  *                   will be valid until next call to client_start/client_step
0952  *                   NULL if mech doesn't include initial client challenge
0953  *  mech          -- set to mechansm name of selected mechanism (may be NULL)
0954  *
0955  * Returns:
0956  *  SASL_OK       -- success
0957  *  SASL_NOMEM    -- not enough memory
0958  *  SASL_NOMECH   -- no mechanism meets requested properties
0959  *  SASL_INTERACT -- user interaction needed to fill in prompt_need list
0960  */
0961 LIBSASL_API int sasl_client_start(sasl_conn_t *conn,
0962                   const char *mechlist,
0963                   sasl_interact_t **prompt_need,
0964                   const char **clientout,
0965                   unsigned *clientoutlen,
0966                   const char **mech);
0967 
0968 /* do a single authentication step.
0969  *  serverin    -- the server message received by the client, MUST have a NUL
0970  *                 sentinel, not counted by serverinlen
0971  * output:
0972  *  prompt_need -- on SASL_INTERACT, list of prompts needed to continue
0973  *  clientout   -- the client response to send to the server
0974  *                 will be valid until next call to client_start/client_step
0975  *
0976  * returns:
0977  *  SASL_OK        -- success
0978  *  SASL_INTERACT  -- user interaction needed to fill in prompt_need list
0979  *  SASL_BADPROT   -- server protocol incorrect/cancelled
0980  *  SASL_BADSERV   -- server failed mutual auth
0981  */
0982 LIBSASL_API int sasl_client_step(sasl_conn_t *conn,
0983                  const char *serverin,
0984                  unsigned serverinlen,
0985                  sasl_interact_t **prompt_need,
0986                  const char **clientout,
0987                  unsigned *clientoutlen);
0988 
0989 /**************
0990  * Server API *
0991  **************/
0992 
0993 /* initialize server drivers, done once per process
0994  *  callbacks      -- callbacks for all server connections; must include
0995  *                    getopt callback
0996  *  appname        -- name of calling application (for lower level logging)
0997  * results:
0998  *  state          -- server state
0999  * returns:
1000  *  SASL_OK        -- success
1001  *  SASL_BADPARAM  -- error in config file
1002  *  SASL_NOMEM     -- memory failure
1003  *  SASL_BADVERS   -- Mechanism version mismatch
1004  */
1005 LIBSASL_API int sasl_server_init(const sasl_callback_t *callbacks,
1006                  const char *appname);
1007 
1008 /* IP/port syntax:
1009  *  a.b.c.d;p              where a-d are 0-255 and p is 0-65535 port number.
1010  *  e:f:g:h:i:j:k:l;p      where e-l are 0000-ffff lower-case hexidecimal
1011  *  e:f:g:h:i:j:a.b.c.d;p  alternate syntax for previous
1012  *
1013  *  Note that one or more "0" fields in f-k can be replaced with "::"
1014  *  Thus:                 e:f:0000:0000:0000:j:k:l;p
1015  *  can be abbreviated:   e:f::j:k:l;p
1016  *
1017  * A buffer of size 52 is adequate for the longest format with NUL terminator.
1018  */
1019 
1020 /* create context for a single SASL connection
1021  *  service        -- registered name of the service using SASL (e.g. "imap")
1022  *  serverFQDN     -- Fully qualified domain name of server.  NULL means use
1023  *                    gethostname() or equivalent.
1024  *                    Useful for multi-homed servers.
1025  *  user_realm     -- permits multiple user realms on server, NULL = default
1026  *  iplocalport    -- server IPv4/IPv6 domain literal string with port
1027  *                    (if NULL, then mechanisms requiring IPaddr are disabled)
1028  *  ipremoteport   -- client IPv4/IPv6 domain literal string with port
1029  *                    (if NULL, then mechanisms requiring IPaddr are disabled)
1030  *  callbacks      -- callbacks (e.g., authorization, lang, new getopt context)
1031  *  flags          -- usage flags (see above)
1032  * returns:
1033  *  pconn          -- new connection context
1034  *
1035  * returns:
1036  *  SASL_OK        -- success
1037  *  SASL_NOMEM     -- not enough memory
1038  */
1039 LIBSASL_API int sasl_server_new(const char *service,
1040                 const char *serverFQDN,
1041                 const char *user_realm,
1042                 const char *iplocalport,
1043                 const char *ipremoteport,
1044                 const sasl_callback_t *callbacks,
1045                 unsigned flags,
1046                 sasl_conn_t **pconn);
1047 
1048 /* Return an array of NUL-terminated strings, terminated by a NULL pointer,
1049  * which lists all possible mechanisms that the library can supply
1050  *
1051  * Returns NULL on failure. */
1052 LIBSASL_API const char ** sasl_global_listmech(void);
1053 
1054 /* This returns a list of mechanisms in a NUL-terminated string
1055  *  conn          -- the connection to list mechanisms for (either client
1056  *                   or server)
1057  *  user          -- restricts mechanisms to those available to that user
1058  *                   (may be NULL, not used for client case)
1059  *  prefix        -- appended to beginning of result
1060  *  sep           -- appended between mechanisms
1061  *  suffix        -- appended to end of result
1062  * results:
1063  *  result        -- NUL terminated result which persists until next
1064  *                   call to sasl_listmech for this sasl_conn_t
1065  *  plen          -- gets length of result (excluding NUL), may be NULL
1066  *  pcount        -- gets number of mechanisms, may be NULL
1067  *
1068  * returns:
1069  *  SASL_OK        -- success
1070  *  SASL_NOMEM     -- not enough memory
1071  *  SASL_NOMECH    -- no enabled mechanisms
1072  */
1073 LIBSASL_API int sasl_listmech(sasl_conn_t *conn,
1074                   const char *user,
1075                   const char *prefix,
1076                   const char *sep,
1077                   const char *suffix,
1078                   const char **result,
1079                   unsigned *plen,
1080                   int *pcount);
1081 
1082 /* start a mechanism exchange within a connection context
1083  *  mech           -- the mechanism name client requested
1084  *  clientin       -- client initial response (NUL terminated), NULL if empty
1085  *  clientinlen    -- length of initial response
1086  *  serverout      -- initial server challenge, NULL if done 
1087  *                    (library handles freeing this string)
1088  *  serveroutlen   -- length of initial server challenge
1089  * output:
1090  *  pconn          -- the connection negotiation state on success
1091  *
1092  * Same returns as sasl_server_step() or
1093  * SASL_NOMECH if mechanism not available.
1094  */
1095 LIBSASL_API int sasl_server_start(sasl_conn_t *conn,
1096                   const char *mech,
1097                   const char *clientin,
1098                   unsigned clientinlen,
1099                   const char **serverout,
1100                   unsigned *serveroutlen);
1101 
1102 /* perform one step of the SASL exchange
1103  *  inputlen & input -- client data
1104  *                      NULL on first step if no optional client step
1105  *  outputlen & output -- set to the server data to transmit
1106  *                        to the client in the next step
1107  *                        (library handles freeing this)
1108  *
1109  * returns:
1110  *  SASL_OK        -- exchange is complete.
1111  *  SASL_CONTINUE  -- indicates another step is necessary.
1112  *  SASL_TRANS     -- entry for user exists, but not for mechanism
1113  *                    and transition is possible
1114  *  SASL_BADPARAM  -- service name needed
1115  *  SASL_BADPROT   -- invalid input from client
1116  *  ...
1117  */
1118 LIBSASL_API int sasl_server_step(sasl_conn_t *conn,
1119                  const char *clientin,
1120                  unsigned clientinlen,
1121                  const char **serverout,
1122                  unsigned *serveroutlen);
1123 
1124 /* check if an apop exchange is valid
1125  *  (note this is an optional part of the SASL API)
1126  *  if challenge is NULL, just check if APOP is enabled
1127  * inputs:
1128  *  challenge     -- challenge which was sent to client
1129  *  challen       -- length of challenge, 0 = strlen(challenge)
1130  *  response      -- client response, "<user> <digest>" (RFC 1939)
1131  *  resplen       -- length of response, 0 = strlen(response)
1132  * returns 
1133  *  SASL_OK       -- success
1134  *  SASL_BADAUTH  -- authentication failed
1135  *  SASL_BADPARAM -- missing challenge
1136  *  SASL_BADPROT  -- protocol error (e.g., response in wrong format)
1137  *  SASL_NOVERIFY -- user found, but no verifier
1138  *  SASL_NOMECH   -- mechanism not supported
1139  *  SASL_NOUSER   -- user not found
1140  */
1141 LIBSASL_API int sasl_checkapop(sasl_conn_t *conn,
1142                    const char *challenge, unsigned challen,
1143                    const char *response, unsigned resplen);
1144 
1145 /* check if a plaintext password is valid
1146  *   if user is NULL, check if plaintext passwords are enabled
1147  * inputs:
1148  *  user          -- user to query in current user_domain
1149  *  userlen       -- length of username, 0 = strlen(user)
1150  *  pass          -- plaintext password to check
1151  *  passlen       -- length of password, 0 = strlen(pass)
1152  * returns 
1153  *  SASL_OK       -- success
1154  *  SASL_NOMECH   -- mechanism not supported
1155  *  SASL_NOVERIFY -- user found, but no verifier
1156  *  SASL_NOUSER   -- user not found
1157  */
1158 LIBSASL_API int sasl_checkpass(sasl_conn_t *conn,
1159                    const char *user, unsigned userlen,
1160                    const char *pass, unsigned passlen);
1161 
1162 /* check if a user exists on server
1163  *  conn          -- connection context
1164  *  service       -- registered name of the service using SASL (e.g. "imap")
1165  *  user_realm    -- permits multiple user realms on server, NULL = default
1166  *  user          -- NUL terminated user name
1167  *
1168  * returns:
1169  *  SASL_OK       -- success
1170  *  SASL_DISABLED -- account disabled
1171  *  SASL_NOUSER   -- user not found
1172  *  SASL_NOVERIFY -- user found, but no usable mechanism
1173  *  SASL_NOMECH   -- no mechanisms enabled
1174  *  SASL_UNAVAIL  -- remote authentication server unavailable, try again later
1175  */
1176 LIBSASL_API int sasl_user_exists(sasl_conn_t *conn,
1177                  const char *service,
1178                  const char *user_realm,
1179                  const char *user);
1180 
1181 /* set the password for a user
1182  *  conn        -- SASL connection
1183  *  user        -- user name
1184  *  pass        -- plaintext password, may be NULL to remove user
1185  *  passlen     -- length of password, 0 = strlen(pass)
1186  *  oldpass     -- NULL will sometimes work
1187  *  oldpasslen  -- length of password, 0 = strlen(oldpass)
1188  *  flags       -- see flags below
1189  * 
1190  * returns:
1191  *  SASL_NOCHANGE  -- proper entry already exists
1192  *  SASL_NOMECH    -- no authdb supports password setting as configured
1193  *  SASL_NOVERIFY  -- user exists, but no settable password present
1194  *  SASL_DISABLED  -- account disabled
1195  *  SASL_PWLOCK    -- password locked
1196  *  SASL_WEAKPASS  -- password too weak for security policy
1197  *  SASL_NOUSERPASS -- user-supplied passwords not permitted
1198  *  SASL_FAIL      -- OS error
1199  *  SASL_BADPARAM  -- password too long
1200  *  SASL_OK        -- successful
1201  */
1202 LIBSASL_API int sasl_setpass(sasl_conn_t *conn,
1203                  const char *user,
1204                  const char *pass, unsigned passlen,
1205                  const char *oldpass, unsigned oldpasslen,
1206                  unsigned flags);
1207 #define SASL_SET_CREATE  0x01   /* create a new entry for user */
1208 #define SASL_SET_DISABLE 0x02   /* disable user account */
1209 #define SASL_SET_NOPLAIN 0x04   /* do not store secret in plain text */
1210 #define SASL_SET_CURMECH_ONLY 0x08  /* set the mechanism specific password only.
1211                        fail if no current mechanism */
1212 
1213 /*********************************************************
1214  * Auxiliary Property Support -- added by cjn 1999-09-29 *
1215  *********************************************************/
1216 
1217 #define SASL_AUX_END      NULL  /* last auxiliary property */
1218 
1219 #define SASL_AUX_ALL "*" /* A special flag to signal user deletion */
1220 
1221 /* traditional Posix items (should be implemented on Posix systems) */
1222 #define SASL_AUX_PASSWORD_PROP "userPassword" /* User Password */
1223 #define SASL_AUX_PASSWORD "*" SASL_AUX_PASSWORD_PROP /* User Password (of authid) */
1224 #define SASL_AUX_UIDNUM   "uidNumber"   /* UID number for the user */
1225 #define SASL_AUX_GIDNUM   "gidNumber"   /* GID for the user */
1226 #define SASL_AUX_FULLNAME "gecos"   /* full name of the user, unix-style */
1227 #define SASL_AUX_HOMEDIR  "homeDirectory" /* home directory for user */
1228 #define SASL_AUX_SHELL    "loginShell"  /* login shell for the user */
1229 
1230 /* optional additional items (not necessarily implemented) */
1231 /* single preferred mail address for user canonically-quoted
1232  * RFC821/822 syntax */
1233 #define SASL_AUX_MAILADDR "mail"
1234 /* path to unix-style mailbox for user */
1235 #define SASL_AUX_UNIXMBX  "mailMessageStore"
1236 /* SMTP mail channel name to use if user authenticates successfully */
1237 #define SASL_AUX_MAILCHAN "mailSMTPSubmitChannel"
1238 
1239 /* Request a set of auxiliary properties
1240  *  conn         connection context
1241  *  propnames    list of auxiliary property names to request ending with
1242  *               NULL.  
1243  *
1244  * Subsequent calls will add items to the request list.  Call with NULL
1245  * to clear the request list.
1246  *
1247  * errors
1248  *  SASL_OK       -- success
1249  *  SASL_BADPARAM -- bad count/conn parameter
1250  *  SASL_NOMEM    -- out of memory
1251  */
1252 LIBSASL_API int sasl_auxprop_request(sasl_conn_t *conn,
1253                      const char **propnames);
1254 
1255 /* Returns current auxiliary property context.
1256  * Use functions in prop.h to access content
1257  *
1258  *  if authentication hasn't completed, property values may be empty/NULL
1259  *
1260  *  properties not recognized by active plug-ins will be left empty/NULL
1261  *
1262  *  returns NULL if conn is invalid.
1263  */
1264 LIBSASL_API struct propctx *sasl_auxprop_getctx(sasl_conn_t *conn);
1265 
1266 /* Store the set of auxiliary properties for the given user.
1267  * Use functions in prop.h to set the content.
1268  *
1269  *  conn         connection context
1270  *  ctx          property context from prop_new()/prop_request()/prop_set()
1271  *  user         NUL terminated user
1272  *
1273  * Call with NULL 'ctx' to see if the backend allows storing properties.
1274  *
1275  * errors
1276  *  SASL_OK       -- success
1277  *  SASL_NOMECH   -- can not store some/all properties
1278  *  SASL_BADPARAM -- bad conn/ctx/user parameter
1279  *  SASL_NOMEM    -- out of memory
1280  *  SASL_FAIL     -- failed to store
1281  */
1282 LIBSASL_API int sasl_auxprop_store(sasl_conn_t *conn,
1283                    struct propctx *ctx, const char *user);
1284 
1285 /**********************
1286  * security layer API *
1287  **********************/
1288 
1289 /* encode a block of data for transmission using security layer,
1290  *  returning the input buffer if there is no security layer.
1291  *  output is only valid until next call to sasl_encode or sasl_encodev
1292  * returns:
1293  *  SASL_OK      -- success (returns input if no layer negotiated)
1294  *  SASL_NOTDONE -- security layer negotiation not finished
1295  *  SASL_BADPARAM -- inputlen is greater than the SASL_MAXOUTBUF
1296  */
1297 LIBSASL_API int sasl_encode(sasl_conn_t *conn,
1298                 const char *input, unsigned inputlen,
1299                 const char **output, unsigned *outputlen);
1300 
1301 /* encode a block of data for transmission using security layer
1302  *  output is only valid until next call to sasl_encode or sasl_encodev
1303  * returns:
1304  *  SASL_OK      -- success (returns input if no layer negotiated)
1305  *  SASL_NOTDONE -- security layer negotiation not finished
1306  *  SASL_BADPARAM -- input length is greater than the SASL_MAXOUTBUF
1307  *           or no security layer
1308  */
1309 LIBSASL_API int sasl_encodev(sasl_conn_t *conn,
1310                  const struct iovec *invec, unsigned numiov,
1311                  const char **output, unsigned *outputlen);
1312 
1313 /* decode a block of data received using security layer
1314  *  returning the input buffer if there is no security layer.
1315  *  output is only valid until next call to sasl_decode
1316  *
1317  *  if outputlen is 0 on return, than the value of output is undefined.
1318  *  
1319  * returns:
1320  *  SASL_OK      -- success (returns input if no layer negotiated)
1321  *  SASL_NOTDONE -- security layer negotiation not finished
1322  *  SASL_BADMAC  -- bad message integrity check
1323  */
1324 LIBSASL_API int sasl_decode(sasl_conn_t *conn,
1325                 const char *input, unsigned inputlen,
1326                 const char **output, unsigned *outputlen);
1327 
1328 #ifdef __cplusplus
1329 }
1330 #endif
1331 
1332 #endif /* SASL_H */