| sasl.h | | sasl.h | |
| /* This is a proposed C API for support of SASL | | /* This is a proposed C API for support of SASL | |
| * | | * | |
|
| | | *********************************IMPORTANT****************************** | |
| | | * send email to chris.newman@innosoft.com and sasl-bugs@andrew.cmu.edu * | |
| | | * if you need to add new error codes, callback types, property values, * | |
| | | * etc. It is important to keep the multiple implementations of this * | |
| | | * API from diverging. * | |
| | | *********************************IMPORTANT****************************** | |
| | | * | |
| * Basic Type Summary: | | * Basic Type Summary: | |
| * sasl_conn_t Context for a SASL connection negotiation | | * sasl_conn_t Context for a SASL connection negotiation | |
| * sasl_ssf_t Security layer Strength Factor | | * sasl_ssf_t Security layer Strength Factor | |
| * sasl_callback_t A typed client/server callback function and context | | * sasl_callback_t A typed client/server callback function and context | |
| * sasl_interact_t A client interaction descriptor | | * sasl_interact_t A client interaction descriptor | |
|
| * sasl_secret_t A client authentication secret/credentials/passphrase | | * sasl_secret_t A client password | |
| * sasl_rand_t Random data context structure | | * sasl_rand_t Random data context structure | |
| * sasl_security_properties_t An application's required security level | | * sasl_security_properties_t An application's required security level | |
|
| * sasl_external_properties_t Security provided by an external security l
ayer | | | |
| * | | * | |
| * Callbacks: | | * Callbacks: | |
| * sasl_getopt_t client/server: Get an option value | | * sasl_getopt_t client/server: Get an option value | |
|
| * sasl_log_t client/server: Log message handler | | * sasl_logmsg_t client/server: Log message handler | |
| * sasl_getpath_t client/server: Get path to search for mechanisms | | | |
| * sasl_getsimple_t client: Get user/language list | | * sasl_getsimple_t client: Get user/language list | |
| * sasl_getsecret_t client: Get authentication secret | | * sasl_getsecret_t client: Get authentication secret | |
| * sasl_chalprompt_t client: Display challenge and prompt for response | | * sasl_chalprompt_t client: Display challenge and prompt for response | |
|
| * sasl_authorize_t server: Authorize policy callback | | * | |
| * sasl_server_getsecret_t server: User secret database read | | * Server only Callbacks: | |
| * sasl_server_putsecret_t server: User secret database write | | * sasl_authorize_t user authorization policy callback | |
| | | * sasl_server_userdb_checkpass check password and auxprops in userdb | |
| | | * sasl_server_userdb_setpass set password in userdb | |
| | | * sasl_server_canon_user canonicalize username routine | |
| * | | * | |
| * Client/Server Function Summary: | | * Client/Server Function Summary: | |
| * sasl_done Release all SASL global state | | * sasl_done Release all SASL global state | |
| * sasl_dispose Connection done: Dispose of sasl_conn_t | | * sasl_dispose Connection done: Dispose of sasl_conn_t | |
| * sasl_getprop Get property (e.g., user name, security layer info) | | * sasl_getprop Get property (e.g., user name, security layer info) | |
| * sasl_setprop Set property (e.g., external ssf) | | * sasl_setprop Set property (e.g., external ssf) | |
|
| * sasl_usererr Translate server error code to user error code | | * sasl_errdetail Generate string from last error on connection | |
| * sasl_errstring Translate sasl error code to a string | | * sasl_errstring Translate sasl error code to a string | |
| * sasl_encode Encode data to send using security layer | | * sasl_encode Encode data to send using security layer | |
| * sasl_decode Decode data received using security layer | | * sasl_decode Decode data received using security layer | |
| * | | * | |
|
| | | * Utility functions: | |
| | | * sasl_encode64 Encode data to send using security layer | |
| | | * sasl_decode64 Decode data received using security layer | |
| | | * sasl_erasebuffer Erase a buffer | |
| | | * | |
| * Client Function Summary: | | * Client Function Summary: | |
| * sasl_client_init Load and initialize client plug-ins (call once) | | * sasl_client_init Load and initialize client plug-ins (call once) | |
| * sasl_client_new Initialize client connection context: sasl_conn_t | | * sasl_client_new Initialize client connection context: sasl_conn_t | |
| * sasl_client_start Select mechanism for connection | | * sasl_client_start Select mechanism for connection | |
| * sasl_client_step Perform one authentication step | | * sasl_client_step Perform one authentication step | |
|
| * sasl_client_auth Create client secret (e.g., from a user & passphrase) | | | |
| * sasl_free_secret Erase & Dispose of a sasl_secret_t | | | |
| * | | * | |
| * Server Function Summary | | * Server Function Summary | |
| * sasl_server_init Load and initialize server plug-ins (call once) | | * sasl_server_init Load and initialize server plug-ins (call once) | |
| * sasl_server_new Initialize server connection context: sasl_conn_t | | * sasl_server_new Initialize server connection context: sasl_conn_t | |
| * sasl_listmech Create list of available mechanisms | | * sasl_listmech Create list of available mechanisms | |
| * sasl_server_start Begin an authentication exchange | | * sasl_server_start Begin an authentication exchange | |
| * sasl_server_step Perform one authentication exchange step | | * sasl_server_step Perform one authentication exchange step | |
| * sasl_checkpass Check a plaintext passphrase | | * sasl_checkpass Check a plaintext passphrase | |
|
| * sasl_userexists Check if user exists | | * sasl_checkapop Check an APOP challenge/response (uses pseudo "APOP" | |
| | | * mechanism similar to CRAM-MD5 mechanism; optional) | |
| | | * sasl_user_exists Check if user exists | |
| * sasl_setpass Change a password or add a user entry | | * sasl_setpass Change a password or add a user entry | |
|
| | | * sasl_auxprop_request Request auxiliary properties | |
| | | * sasl_auxprop_getctx Get auxiliary property context for connection | |
| * | | * | |
| * Basic client model: | | * Basic client model: | |
| * 1. client calls sasl_client_init() at startup to load plug-ins | | * 1. client calls sasl_client_init() at startup to load plug-ins | |
| * 2. when connection formed, call sasl_client_new() | | * 2. when connection formed, call sasl_client_new() | |
| * 3. once list of supported mechanisms received from server, client | | * 3. once list of supported mechanisms received from server, client | |
| * calls sasl_client_start(). goto 4a | | * calls sasl_client_start(). goto 4a | |
| * 4. client calls sasl_client_step() | | * 4. client calls sasl_client_step() | |
| * [4a. If SASL_INTERACT, fill in prompts and goto 4 | | * [4a. If SASL_INTERACT, fill in prompts and goto 4 | |
| * -- doesn't happen if callbacks provided] | | * -- doesn't happen if callbacks provided] | |
| * 4b. If SASL error, goto 7 or 3 | | * 4b. If SASL error, goto 7 or 3 | |
| | | | |
| skipping to change at line 74 | | skipping to change at line 89 | |
| * 5b. On failure goto 7 or 3 | | * 5b. On failure goto 7 or 3 | |
| * 5c. On success with no server response continue | | * 5c. On success with no server response continue | |
| * 6. continue with application protocol until connection closes | | * 6. continue with application protocol until connection closes | |
| * call sasl_getprop/sasl_encode/sasl_decode() if using security layer | | * call sasl_getprop/sasl_encode/sasl_decode() if using security layer | |
| * 7. call sasl_dispose(), may return to step 2 | | * 7. call sasl_dispose(), may return to step 2 | |
| * 8. call sasl_done() when program terminates | | * 8. call sasl_done() when program terminates | |
| * | | * | |
| * Basic Server model: | | * Basic Server model: | |
| * 1. call sasl_server_init() at startup to load plug-ins | | * 1. call sasl_server_init() at startup to load plug-ins | |
| * 2. On connection, call sasl_server_new() | | * 2. On connection, call sasl_server_new() | |
|
| * [3. call sasl_listmech() and send list to client] | | * 3. call sasl_listmech() and send list to client] | |
| * 4. after client AUTH command, call sasl_server_start(), goto 5a | | * 4. after client AUTH command, call sasl_server_start(), goto 5a | |
| * 5. call sasl_server_step() | | * 5. call sasl_server_step() | |
| * 5a. If SASL_CONTINUE, output to client, wait response, repeat 5 | | * 5a. If SASL_CONTINUE, output to client, wait response, repeat 5 | |
| * 5b. If SASL error, then goto 7 | | * 5b. If SASL error, then goto 7 | |
| * 5c. If SASL_OK, move on | | * 5c. If SASL_OK, move on | |
| * 6. continue with application protocol until connection closes | | * 6. continue with application protocol until connection closes | |
|
| | | * call sasl_getprop to get username | |
| * call sasl_getprop/sasl_encode/sasl_decode() if using security layer | | * call sasl_getprop/sasl_encode/sasl_decode() if using security layer | |
| * 7. call sasl_dispose(), may return to step 2 | | * 7. call sasl_dispose(), may return to step 2 | |
| * 8. call sasl_done() when program terminates | | * 8. call sasl_done() when program terminates | |
| * | | * | |
|
| | | ************************************************* | |
| | | * IMPORTANT NOTE: server realms / username syntax | |
| | | * | |
| | | * If a user name contains a "@", then the rightmost "@" in the user name | |
| | | * separates the account name from the realm in which this account is | |
| | | * located. A single server may support multiple realms. If the | |
| | | * server knows the realm at connection creation time (e.g., a server | |
| | | * with multiple IP addresses tightly binds one address to a specific | |
| | | * realm) then that realm must be passed in the user_realm field of | |
| | | * the sasl_server_new call. If user_realm is non-empty and an | |
| | | * unqualified user name is supplied, then the canon_user facility is | |
| | | * expected to append "@" and user_realm to the user name. The canon_user | |
| | | * facility may treat other characters such as "%" as equivalent to "@". | |
| | | * | |
| | | * If the server forbids the use of "@" in user names for other | |
| | | * purposes, this simplifies security validation. | |
| */ | | */ | |
| | | | |
| #ifndef SASL_H | | #ifndef SASL_H | |
| #define SASL_H 1 | | #define SASL_H 1 | |
| | | | |
|
| #define SASL_VERSION_MAJOR 1 | | #define SASL_VERSION_MAJOR 2 | |
| #define SASL_VERSION_MINOR 5 | | #define SASL_VERSION_MINOR 1 | |
| #define SASL_VERSION_STEP 28 | | #define SASL_VERSION_STEP 2 | |
| | | | |
| /* The following ifdef block is the standard way of creating macros | | #include "prop.h" | |
| * which make exporting from a DLL simpler. All files within this DLL | | #define LIBSASL_API | |
| * are compiled with the LIBSASL_EXPORTS symbol defined on the command | | | |
| * line. this symbol should not be defined on any project that uses | | | |
| * this DLL. This way any other project whose source files include | | | |
| * this file see LIBSASL_API functions as being imported from a DLL, | | | |
| * wheras this DLL sees symbols defined with this macro as being | | | |
| * exported. */ | | | |
| /* Under Unix, life is simpler: we just need to mark library functions | | | |
| * as extern. (Technically, we don't even have to do that.) */ | | | |
| #ifdef WIN32 | | | |
| # ifdef LIBSASL_EXPORTS | | | |
| # define LIBSASL_API __declspec(dllexport) | | | |
| # else /* LIBSASL_EXPORTS */ | | | |
| # define LIBSASL_API __declspec(dllimport) | | | |
| # endif /* LIBSASL_EXPORTS */ | | | |
| #else /* WIN32 */ | | | |
| # define LIBSASL_API extern | | | |
| #endif /* WIN32 */ | | | |
| | | | |
| /************* | | /************* | |
| * Basic API * | | * Basic API * | |
| *************/ | | *************/ | |
| | | | |
| /* SASL result codes: */ | | /* SASL result codes: */ | |
|
| #define SASL_CONTINUE (1) /* another step is needed in authentication */ | | #define SASL_CONTINUE 1 /* another step is needed in authentication */ | |
| #define SASL_OK (0) /* successful result */ | | #define SASL_OK 0 /* successful result */ | |
| #define SASL_FAIL (-1) /* generic failure */ | | #define SASL_FAIL -1 /* generic failure */ | |
| #define SASL_NOMEM (-2) /* memory shortage failure */ | | #define SASL_NOMEM -2 /* memory shortage failure */ | |
| #define SASL_BUFOVER (-3) /* overflowed buffer */ | | #define SASL_BUFOVER -3 /* overflowed buffer */ | |
| #define SASL_NOMECH (-4) /* mechanism not supported */ | | #define SASL_NOMECH -4 /* mechanism not supported */ | |
| #define SASL_BADPROT (-5) /* bad protocol / cancel */ | | #define SASL_BADPROT -5 /* bad protocol / cancel */ | |
| #define SASL_NOTDONE (-6) /* can't request info until later in exchange | | #define SASL_NOTDONE -6 /* can't request info until later in exchange | |
| */ | | */ | |
| #define SASL_BADPARAM (-7) /* invalid parameter supplied */ | | #define SASL_BADPARAM -7 /* invalid parameter supplied */ | |
| #define SASL_TRYAGAIN (-8) /* transient failure (e.g., weak key) */ | | #define SASL_TRYAGAIN -8 /* transient failure (e.g., weak key) */ | |
| #define SASL_BADMAC (-9) /* integrity check failed */ | | #define SASL_BADMAC -9 /* integrity check failed */ | |
| | | #define SASL_NOTINIT -12 /* SASL library not initialized */ | |
| /* -- client only codes -- */ | | /* -- client only codes -- */ | |
|
| #define SASL_INTERACT (2) /* needs user interaction */ | | #define SASL_INTERACT 2 /* needs user interaction */ | |
| #define SASL_BADSERV (-10) /* server failed mutual authentication step */ | | #define SASL_BADSERV -10 /* server failed mutual authentication step */ | |
| #define SASL_WRONGMECH (-11) /* mechanism doesn't support requested feature | | #define SASL_WRONGMECH -11 /* mechanism doesn't support requested feature | |
| */ | | */ | |
| #define SASL_NEWSECRET (-12) /* new secret needed */ | | | |
| /* -- server only codes -- */ | | /* -- server only codes -- */ | |
|
| #define SASL_BADAUTH (-13) /* authentication failure */ | | #define SASL_BADAUTH -13 /* authentication failure */ | |
| #define SASL_NOAUTHZ (-14) /* authorization failure */ | | #define SASL_NOAUTHZ -14 /* authorization failure */ | |
| #define SASL_TOOWEAK (-15) /* mechanism too weak for this user */ | | #define SASL_TOOWEAK -15 /* mechanism too weak for this user */ | |
| #define SASL_ENCRYPT (-16) /* encryption needed to use mechanism */ | | #define SASL_ENCRYPT -16 /* encryption needed to use mechanism */ | |
| #define SASL_TRANS (-17) /* One time use of a plaintext password will | | #define SASL_TRANS -17 /* One time use of a plaintext password will | |
| enable requested mechanism for user */ | | enable requested mechanism for user */ | |
|
| #define SASL_EXPIRED (-18) /* passphrase expired, has to be reset */ | | #define SASL_EXPIRED -18 /* passphrase expired, has to be reset */ | |
| #define SASL_DISABLED (-19) /* account disabled */ | | #define SASL_DISABLED -19 /* account disabled */ | |
| #define SASL_NOUSER (-20) /* user not found */ | | #define SASL_NOUSER -20 /* user not found */ | |
| #define SASL_PWLOCK (-21) /* password locked */ | | #define SASL_BADVERS -23 /* version mismatch with plug-in */ | |
| #define SASL_NOCHANGE (-22) /* requested change was not needed */ | | #define SASL_UNAVAIL -24 /* remote authentication server unavailable */ | |
| #define SASL_BADVERS (-23) /* version mismatch with plug-in */ | | #define SASL_NOVERIFY -26 /* user exists, but no verifier for user */ | |
| | | /* -- codes for password setting -- */ | |
| #define SASL_NOPATH (-25) /* path not set */ | | #define SASL_PWLOCK -21 /* passphrase locked */ | |
| | | #define SASL_NOCHANGE -22 /* requested change was not needed */ | |
| | | #define SASL_WEAKPASS -27 /* passphrase is too weak for security policy | |
| | | */ | |
| | | #define SASL_NOUSERPASS -28 /* user supplied passwords not permitted */ | |
| | | | |
| /* max size of a sasl mechanism name */ | | /* max size of a sasl mechanism name */ | |
| #define SASL_MECHNAMEMAX 20 | | #define SASL_MECHNAMEMAX 20 | |
| | | | |
|
| | | #ifdef _WIN32 | |
| | | /* Define to have the same layout as a WSABUF */ | |
| | | #ifndef STRUCT_IOVEC_DEFINED | |
| | | #define STRUCT_IOVEC_DEFINED 1 | |
| | | struct iovec { | |
| | | long iov_len; | |
| | | char *iov_base; | |
| | | }; | |
| | | #endif | |
| | | #else | |
| | | struct iovec; /* Defined in OS headers */ | |
| | | #endif | |
| | | | |
| /* per-connection SASL negotiation state for client or server | | /* per-connection SASL negotiation state for client or server | |
| */ | | */ | |
| typedef struct sasl_conn sasl_conn_t; | | typedef struct sasl_conn sasl_conn_t; | |
| | | | |
|
| /* opaque passphrase/secret kept encrypted by API middleware | | /* Plain text password structure. | |
| * can be used by caller for single sign-on | | * len is the length of the password, data is the text. | |
| * client "KEY" option will be used as key for | | | |
| * clients which offer a save-to-disk option. | | | |
| */ | | */ | |
| typedef struct sasl_secret { | | typedef struct sasl_secret { | |
| unsigned long len; | | unsigned long len; | |
|
| char data[1]; /* variable sized */ | | unsigned char data[1]; /* variable sized */ | |
| } sasl_secret_t; | | } sasl_secret_t; | |
| | | | |
| /* random data context structure | | /* random data context structure | |
| */ | | */ | |
| typedef struct sasl_rand_s sasl_rand_t; | | typedef struct sasl_rand_s sasl_rand_t; | |
| | | | |
| /**************************** | | /**************************** | |
| * Configure Basic Services * | | * Configure Basic Services * | |
| ****************************/ | | ****************************/ | |
| | | | |
| | | | |
| skipping to change at line 190 | | skipping to change at line 219 | |
| /* memory allocation functions which may optionally be replaced: | | /* memory allocation functions which may optionally be replaced: | |
| */ | | */ | |
| typedef void *sasl_malloc_t(unsigned long); | | typedef void *sasl_malloc_t(unsigned long); | |
| typedef void *sasl_calloc_t(unsigned long, unsigned long); | | typedef void *sasl_calloc_t(unsigned long, unsigned long); | |
| typedef void *sasl_realloc_t(void *, unsigned long); | | typedef void *sasl_realloc_t(void *, unsigned long); | |
| typedef void sasl_free_t(void *); | | typedef void sasl_free_t(void *); | |
| | | | |
| LIBSASL_API void sasl_set_alloc(sasl_malloc_t *, | | LIBSASL_API void sasl_set_alloc(sasl_malloc_t *, | |
| sasl_calloc_t *, | | sasl_calloc_t *, | |
| sasl_realloc_t *, | | sasl_realloc_t *, | |
|
| sasl_free_t *); | | sasl_free_t *); | |
| | | | |
| /* mutex functions which may optionally be replaced: | | /* mutex functions which may optionally be replaced: | |
|
| * sasl_mutex_new allocates a mutex structure | | * sasl_mutex_alloc allocates a mutex structure | |
| * sasl_mutex_lock blocks until mutex locked | | * sasl_mutex_lock blocks until mutex locked | |
|
| * returns SASL_FAIL on deadlock or parameter error | | * returns -1 on deadlock or parameter error | |
| * returns SASL_OK on success | | * returns 0 on success | |
| * sasl_mutex_unlock unlocks mutex if it's locked | | * sasl_mutex_unlock unlocks mutex if it's locked | |
|
| * returns SASL_FAIL if not locked or parameter error | | * returns -1 if not locked or parameter error | |
| * returns SASL_OK on success | | * returns 0 on success | |
| | | * sasl_mutex_free frees a mutex structure | |
| */ | | */ | |
|
| typedef void *sasl_mutex_new_t(); | | typedef void *sasl_mutex_alloc_t(void); | |
| typedef int sasl_mutex_lock_t(void *mutex); | | typedef int sasl_mutex_lock_t(void *mutex); | |
| typedef int sasl_mutex_unlock_t(void *mutex); | | typedef int sasl_mutex_unlock_t(void *mutex); | |
|
| typedef void sasl_mutex_dispose_t(void *mutex); | | typedef void sasl_mutex_free_t(void *mutex); | |
| | | LIBSASL_API void sasl_set_mutex(sasl_mutex_alloc_t *, sasl_mutex_lock_t *, | |
| LIBSASL_API void sasl_set_mutex(sasl_mutex_new_t *, sasl_mutex_lock_t *, | | sasl_mutex_unlock_t *, sasl_mutex_free_t *); | |
| sasl_mutex_unlock_t *, sasl_mutex_dispose_t | | | |
| *); | | | |
| | | | |
| /***************************** | | /***************************** | |
| * Security preference types * | | * Security preference types * | |
| *****************************/ | | *****************************/ | |
| | | | |
| /* security layer strength factor -- an unsigned integer usable by the call
er | | /* security layer strength factor -- an unsigned integer usable by the call
er | |
| * to specify approximate security layer strength desired. Roughly | | * to specify approximate security layer strength desired. Roughly | |
| * correlated to effective key length for encryption. | | * correlated to effective key length for encryption. | |
| * 0 = no protection | | * 0 = no protection | |
| * 1 = integrity protection only | | * 1 = integrity protection only | |
| * 40 = 40-bit DES or 40-bit RC2/RC4 | | * 40 = 40-bit DES or 40-bit RC2/RC4 | |
| * 56 = DES | | * 56 = DES | |
| * 112 = triple-DES | | * 112 = triple-DES | |
| * 128 = 128-bit RC2/RC4/BLOWFISH | | * 128 = 128-bit RC2/RC4/BLOWFISH | |
|
| | | * 256 = baseline AES | |
| */ | | */ | |
| typedef unsigned sasl_ssf_t; | | typedef unsigned sasl_ssf_t; | |
| | | | |
|
| /* secflags provided on sasl_server_new and sasl_client_new: | | /* usage flags provided to sasl_server_new and sasl_client_new: | |
| */ | | */ | |
|
| #define SASL_SECURITY_LAYER (0x0001) /* caller supports security layer */ | | #define SASL_SUCCESS_DATA 0x0004 /* server supports data on success */ | |
| | | | |
| /*************************** | | /*************************** | |
| * Security Property Types * | | * Security Property Types * | |
| ***************************/ | | ***************************/ | |
| | | | |
| /* Structure specifying the client or server's security policy | | /* Structure specifying the client or server's security policy | |
| * and optional additional properties. | | * and optional additional properties. | |
| */ | | */ | |
| | | | |
| /* These are the various security flags apps can specify. */ | | /* These are the various security flags apps can specify. */ | |
| /* NOPLAINTEXT -- don't permit mechanisms susceptible to simple | | /* NOPLAINTEXT -- don't permit mechanisms susceptible to simple | |
| * passive attack (e.g., PLAIN, LOGIN) | | * passive attack (e.g., PLAIN, LOGIN) | |
| * NOACTIVE -- protection from active (non-dictionary) attacks | | * NOACTIVE -- protection from active (non-dictionary) attacks | |
| * during authentication exchange. | | * during authentication exchange. | |
|
| * Authenticates server. | | * Authenticates server. | |
| * NODICTIONARY -- don't permit mechanisms susceptible to passive | | * NODICTIONARY -- don't permit mechanisms susceptible to passive | |
| * dictionary attack | | * dictionary attack | |
| * FORWARD_SECRECY -- require forward secrecy between sessions | | * FORWARD_SECRECY -- require forward secrecy between sessions | |
| * (breaking one won't help break next) | | * (breaking one won't help break next) | |
| * NOANONYMOUS -- don't permit mechanisms that allow anonymous log
in | | * NOANONYMOUS -- don't permit mechanisms that allow anonymous log
in | |
| * PASS_CREDENTIALS -- require mechanisms which pass client | | * PASS_CREDENTIALS -- require mechanisms which pass client | |
| * credentials, and allow mechanisms which can pass | | * credentials, and allow mechanisms which can pass | |
| * credentials to do so | | * credentials to do so | |
|
| | | * MUTUAL_AUTH -- require mechanisms which provide mutual | |
| | | * authentication | |
| */ | | */ | |
|
| #define SASL_SEC_NOPLAINTEXT (0x0001) | | #define SASL_SEC_NOPLAINTEXT 0x0001 | |
| #define SASL_SEC_NOACTIVE (0x0002) | | #define SASL_SEC_NOACTIVE 0x0002 | |
| #define SASL_SEC_NODICTIONARY (0x0004) | | #define SASL_SEC_NODICTIONARY 0x0004 | |
| #define SASL_SEC_FORWARD_SECRECY (0x0008) | | #define SASL_SEC_FORWARD_SECRECY 0x0008 | |
| #define SASL_SEC_NOANONYMOUS (0x0010) | | #define SASL_SEC_NOANONYMOUS 0x0010 | |
| #define SASL_SEC_PASS_CREDENTIALS (0x0200) | | #define SASL_SEC_PASS_CREDENTIALS 0x0020 | |
| | | #define SASL_SEC_MUTUAL_AUTH 0x0040 | |
| | | #define SASL_SEC_MAXIMUM 0x00FF | |
| | | | |
| typedef struct sasl_security_properties | | typedef struct sasl_security_properties | |
| { | | { | |
| /* security strength factor | | /* security strength factor | |
| * min_ssf = minimum acceptable final level | | * min_ssf = minimum acceptable final level | |
| * max_ssf = maximum acceptable final level | | * max_ssf = maximum acceptable final level | |
| */ | | */ | |
| sasl_ssf_t min_ssf; | | sasl_ssf_t min_ssf; | |
| sasl_ssf_t max_ssf; | | sasl_ssf_t max_ssf; | |
| | | | |
| /* Maximum security layer receive buffer size. | | /* Maximum security layer receive buffer size. | |
| * 0=security layer not supported | | * 0=security layer not supported | |
| */ | | */ | |
| unsigned maxbufsize; | | unsigned maxbufsize; | |
| | | | |
|
| /* bitfield for security properties -- see SASL_SEC_* above */ | | /* bitfield for attacks to protect against */ | |
| int security_flags; | | unsigned security_flags; | |
| | | | |
| /* NULL terminated array of additional property names, values */ | | /* NULL terminated array of additional property names, values */ | |
| const char **property_names; | | const char **property_names; | |
| const char **property_values; | | const char **property_values; | |
| } sasl_security_properties_t; | | } sasl_security_properties_t; | |
| | | | |
|
| /* Structure communicating the characteristics of an external security | | | |
| * mechanism. This is used with sasl_setprop() to inform the library | | | |
| * of an active external security layer. If the auth_id is non-NULL, | | | |
| * this enables the EXTERNAL authentication mechanism; this may also | | | |
| * allow other mechanisms to become active (for instance, if an | | | |
| * application demands encryption, mechanisms which solely provide | | | |
| * authentication might become active if the necessary encryption is | | | |
| * provided external to SASL). Since this potentially changes the | | | |
| * list of supported mechanisms, the mechanism list should be re-sent, | | | |
| * if it has been sent already. */ | | | |
| typedef struct sasl_external_properties | | | |
| { | | | |
| /* security provided by the external mechanism */ | | | |
| sasl_ssf_t ssf; | | | |
| | | | |
| /* authorization identity provided by the external mechanism */ | | | |
| char *auth_id; | | | |
| } sasl_external_properties_t; | | | |
| | | | |
| /****************** | | /****************** | |
| * Callback types * | | * Callback types * | |
| ******************/ | | ******************/ | |
| | | | |
|
| /* Extensible type for a client/server callbacks | | /* | |
| | | * Extensible type for a client/server callbacks | |
| * id -- identifies callback type | | * id -- identifies callback type | |
| * proc -- procedure call arguments vary based on id | | * proc -- procedure call arguments vary based on id | |
| * context -- context passed to procedure | | * context -- context passed to procedure | |
| */ | | */ | |
|
| | | /* Note that any memory that is allocated by the callback needs to be | |
| | | * freed by the application, be it via function call or interaction. | |
| | | * | |
| | | * It may be freed after sasl_*_step returns SASL_OK. if the mechanism | |
| | | * requires this information to persist (for a security layer, for example) | |
| | | * it must maintain a private copy. | |
| | | */ | |
| typedef struct sasl_callback { | | typedef struct sasl_callback { | |
| /* Identifies the type of the callback function. | | /* Identifies the type of the callback function. | |
| * Mechanisms must ignore callbacks with id's they don't recognize. | | * Mechanisms must ignore callbacks with id's they don't recognize. | |
| */ | | */ | |
| unsigned long id; | | unsigned long id; | |
|
| int (*proc)(); /* Callback function. Types of arguments vary by 'id'
*/ | | int (*proc)(); /* Callback function. Types of arguments vary by 'id'
*/ | |
| void *context; | | void *context; | |
| } sasl_callback_t; | | } sasl_callback_t; | |
| | | | |
| /* callback ids & functions: | | /* callback ids & functions: | |
| */ | | */ | |
|
| #define SASL_CB_LIST_END (0) /* end of list */ | | #define SASL_CB_LIST_END 0 /* end of list */ | |
| | | | |
| /* option reading callback -- this allows a SASL configuration to be | | /* option reading callback -- this allows a SASL configuration to be | |
| * encapsulated in the caller's configuration system. Some implementation
s | | * encapsulated in the caller's configuration system. Some implementation
s | |
| * may use default config file(s) if this is omitted. Configuration items | | * may use default config file(s) if this is omitted. Configuration items | |
| * may be plugin-specific and are arbitrary strings. | | * may be plugin-specific and are arbitrary strings. | |
| * | | * | |
| * inputs: | | * inputs: | |
| * context -- option context from callback record | | * context -- option context from callback record | |
| * plugin_name -- name of plugin (NULL = general SASL option) | | * plugin_name -- name of plugin (NULL = general SASL option) | |
| * option -- name of option | | * option -- name of option | |
| * output: | | * output: | |
| * result -- set to result which persists until next getopt in | | * result -- set to result which persists until next getopt in | |
| * same thread, unchanged if option not found | | * same thread, unchanged if option not found | |
|
| * len -- length of result (optional) | | * len -- length of result (may be NULL) | |
| * returns: | | * returns: | |
| * SASL_OK -- no error | | * SASL_OK -- no error | |
| * SASL_FAIL -- error | | * SASL_FAIL -- error | |
| */ | | */ | |
| typedef int sasl_getopt_t(void *context, const char *plugin_name, | | typedef int sasl_getopt_t(void *context, const char *plugin_name, | |
| const char *option, | | const char *option, | |
| const char **result, unsigned *len); | | const char **result, unsigned *len); | |
|
| #define SASL_CB_GETOPT (1) | | #define SASL_CB_GETOPT 1 | |
| | | | |
| /* Logging levels for use with the logging callback function. */ | | /* Logging levels for use with the logging callback function. */ | |
|
| #define SASL_LOG_ERR (1) /* error message */ | | #define SASL_LOG_NONE 0 /* don't log anything */ | |
| #define SASL_LOG_WARNING (2) /* warning message */ | | #define SASL_LOG_ERR 1 /* log unusual errors (default) */ | |
| #define SASL_LOG_INFO (3) /* normal message */ | | #define SASL_LOG_FAIL 2 /* log all authentication failures */ | |
| | | #define SASL_LOG_WARN 3 /* log non-fatal warnings */ | |
| | | #define SASL_LOG_NOTE 4 /* more verbose than LOG_WARN */ | |
| | | #define SASL_LOG_DEBUG 5 /* more verbose than LOG_NOTE */ | |
| | | #define SASL_LOG_TRACE 6 /* traces of internal protocols */ | |
| | | #define SASL_LOG_PASS 7 /* traces of internal protocols, including | |
| | | * passwords */ | |
| | | | |
| /* logging callback -- this allows plugins and the middleware to | | /* logging callback -- this allows plugins and the middleware to | |
| * log operations they perform. | | * log operations they perform. | |
| * inputs: | | * inputs: | |
| * context -- logging context from the callback record | | * context -- logging context from the callback record | |
|
| * priority -- logging priority; see above | | * level -- logging level; see above | |
| * message -- message to log | | * message -- message to log | |
| * returns: | | * returns: | |
| * SASL_OK -- no error | | * SASL_OK -- no error | |
| * SASL_FAIL -- error | | * SASL_FAIL -- error | |
| */ | | */ | |
| typedef int sasl_log_t(void *context, | | typedef int sasl_log_t(void *context, | |
|
| int priority, | | int level, | |
| const char *message); | | const char *message); | |
|
| | | #define SASL_CB_LOG 2 | |
| #define SASL_CB_LOG (2) | | | |
| | | | |
| /* getpath callback -- this allows applications to specify the | | /* getpath callback -- this allows applications to specify the | |
| * colon-separated path to search for plugins (by default, | | * colon-separated path to search for plugins (by default, | |
|
| * taken from the SASL_PATH environment variable). | | * taken from an implementation-specific location). | |
| * inputs: | | * inputs: | |
| * context -- getpath context from the callback record | | * context -- getpath context from the callback record | |
| * outputs: | | * outputs: | |
|
| * path -- colon seperated path (allocated on the heap; the | | * path -- colon seperated path | |
| * library will free it using the sasl_free_t * | | | |
| * passed to sasl_set_alloc(), or the standard free() | | | |
| * library call). | | | |
| * returns: | | * returns: | |
| * SASL_OK -- no error | | * SASL_OK -- no error | |
| * SASL_FAIL -- error | | * SASL_FAIL -- error | |
| */ | | */ | |
|
| typedef int sasl_getpath_t(void * context, | | typedef int sasl_getpath_t(void *context, | |
| char ** path); | | const char **path); | |
| | | | |
|
| #define SASL_CB_GETPATH (3) | | #define SASL_CB_GETPATH 3 | |
| | | | |
| /* verify file callback -- this allows applications to check if they | | /* verify file callback -- this allows applications to check if they | |
| * want SASL to use files, file by file. This is intended to allow | | * want SASL to use files, file by file. This is intended to allow | |
| * applications to sanity check the environment to make sure plugins | | * applications to sanity check the environment to make sure plugins | |
| * or the configuration file can't be written to, etc. | | * or the configuration file can't be written to, etc. | |
| * inputs: | | * inputs: | |
| * context -- verifypath context from the callback record | | * context -- verifypath context from the callback record | |
| * file -- full path to file to verify | | * file -- full path to file to verify | |
|
| * type -- type of file to verify | | * type -- type of file to verify (see below) | |
| | | | |
| * returns: | | * returns: | |
| * SASL_OK -- no error (file can safely be used) | | * SASL_OK -- no error (file can safely be used) | |
| * SASL_CONTINUE -- continue WITHOUT using this file | | * SASL_CONTINUE -- continue WITHOUT using this file | |
| * SASL_FAIL -- error | | * SASL_FAIL -- error | |
| */ | | */ | |
|
| typedef int sasl_verifyfile_t(void * context, | | | |
| const char * file, const int type); | | | |
| | | | |
| #define SASL_CB_VERIFYFILE (4) | | | |
| | | | |
| /* these are the types of files libsasl will ask about */ | | /* these are the types of files libsasl will ask about */ | |
|
| #define SASL_VRFY_PLUGIN (1) | | typedef enum { | |
| #define SASL_VRFY_CONF (2) | | SASL_VRFY_PLUGIN=0, /* a DLL/shared library plug-in */ | |
| #define SASL_VRFY_PASSWD (3) | | SASL_VRFY_CONF=1, /* a configuration file */ | |
| #define SASL_VRFY_OTHER (4) | | SASL_VRFY_PASSWD=2, /* a password storage file/db */ | |
| | | SASL_VRFY_OTHER=3 /* some other file */ | |
| | | } sasl_verify_type_t; | |
| | | | |
| | | typedef int sasl_verifyfile_t(void *context, | |
| | | const char *file, sasl_verify_type_t type); | |
| | | #define SASL_CB_VERIFYFILE 4 | |
| | | | |
| /* client/user interaction callbacks: | | /* client/user interaction callbacks: | |
| */ | | */ | |
|
| /* Simple prompt -- result must persist until next call to getsimple or | | /* Simple prompt -- result must persist until next call to getsimple on | |
| * until connection context is disposed | | * same connection or until connection context is disposed | |
| * inputs: | | * inputs: | |
| * context -- context from callback structure | | * context -- context from callback structure | |
| * id -- callback id | | * id -- callback id | |
| * outputs: | | * outputs: | |
| * result -- set to NUL terminated string | | * result -- set to NUL terminated string | |
| * NULL = user cancel | | * NULL = user cancel | |
| * len -- length of result, ignored with SASL_CB_SECRET | | * len -- length of result, ignored with SASL_CB_SECRET | |
| * returns SASL_OK | | * returns SASL_OK | |
| */ | | */ | |
| typedef int sasl_getsimple_t(void *context, int id, | | typedef int sasl_getsimple_t(void *context, int id, | |
| const char **result, unsigned *len); | | const char **result, unsigned *len); | |
|
| #define SASL_CB_USER (0x4001) /* client user identity to login as */ | | #define SASL_CB_USER 0x4001 /* client user identity to login as */ | |
| #define SASL_CB_AUTHNAME (0x4002) /* client authentication name, | | #define SASL_CB_AUTHNAME 0x4002 /* client authentication name */ | |
| * defaults to authid in sasl_secret_t | | #define SASL_CB_LANGUAGE 0x4003 /* comma separated list of RFC 1766 | |
| */ | | | |
| #define SASL_CB_LANGUAGE (0x4003) /* comma separated list of RFC 1766 | | | |
| * language codes in order of preferenc
e | | * language codes in order of preferenc
e | |
| * to be used to localize client prompt
s | | * to be used to localize client prompt
s | |
| * or server error codes */ | | * or server error codes */ | |
|
| | | #define SASL_CB_CNONCE 0x4007 /* caller supplies client-nonce | |
| | | * primarily for testing purposes */ | |
| | | | |
|
| /* get a sasl_secret_t | | /* get a sasl_secret_t (plaintext password with length) | |
| * psecret -- may be left NULL if sasl_client_auth() called | | * inputs: | |
| | | * conn -- connection context | |
| | | * context -- context from callback structure | |
| | | * id -- callback id | |
| | | * outputs: | |
| | | * psecret -- set to NULL to cancel | |
| | | * set to password structure which must persist until | |
| | | * next call to getsecret in same connection, but middlew | |
| | | are | |
| | | * will erase password data when it's done with it. | |
| * returns SASL_OK | | * returns SASL_OK | |
| */ | | */ | |
| typedef int sasl_getsecret_t(sasl_conn_t *conn, void *context, int id, | | typedef int sasl_getsecret_t(sasl_conn_t *conn, void *context, int id, | |
| sasl_secret_t **psecret); | | sasl_secret_t **psecret); | |
|
| #define SASL_CB_PASS (0x4004) /* client passphrase-based secret */ | | #define SASL_CB_PASS 0x4004 /* client passphrase-based secret */ | |
| | | | |
|
| /* prompt for input in response to a challenge, result is copied & erased | | /* prompt for input in response to a challenge. | |
| * by caller. | | | |
| * input: | | * input: | |
| * context -- context from callback structure | | * context -- context from callback structure | |
| * id -- callback id | | * id -- callback id | |
| * challenge -- server challenge | | * challenge -- server challenge | |
| * output: | | * output: | |
| * result -- NUL terminated result, NULL = user cancel | | * result -- NUL terminated result, NULL = user cancel | |
| * len -- length of result | | * len -- length of result | |
| * returns SASL_OK | | * returns SASL_OK | |
| */ | | */ | |
| typedef int sasl_chalprompt_t(void *context, int id, | | typedef int sasl_chalprompt_t(void *context, int id, | |
| const char *challenge, | | const char *challenge, | |
| const char *prompt, const char *defresult, | | const char *prompt, const char *defresult, | |
| const char **result, unsigned *len); | | const char **result, unsigned *len); | |
|
| #define SASL_CB_ECHOPROMPT (0x4005) /* challenge and client-entered resul | | #define SASL_CB_ECHOPROMPT 0x4005 /* challenge and client enterred result | |
| t */ | | */ | |
| #define SASL_CB_NOECHOPROMPT (0x4006) /* challenge and client-entered resul | | #define SASL_CB_NOECHOPROMPT 0x4006 /* challenge and client enterred result | |
| t */ | | */ | |
| | | | |
| /* prompt (or autoselect) the realm to do authentication in. | | /* prompt (or autoselect) the realm to do authentication in. | |
| * may get a list of valid realms. | | * may get a list of valid realms. | |
| * input: | | * input: | |
| * context -- context from callback structure | | * context -- context from callback structure | |
| * id -- callback id | | * id -- callback id | |
| * availrealms -- available realms; string list; NULL terminated | | * availrealms -- available realms; string list; NULL terminated | |
|
| | | * list may be empty. | |
| * output: | | * output: | |
| * result -- NUL terminated realm; NULL is equivalent to "" | | * result -- NUL terminated realm; NULL is equivalent to "" | |
| * returns SASL_OK | | * returns SASL_OK | |
| * result must persist until the next callback | | * result must persist until the next callback | |
| */ | | */ | |
|
| /* If there is an interaction with SASL_CB_GETREALM the challenge of | | | |
| * the sasl_interact_t will be of the format: {realm1, realm2, | | | |
| * ...}. That is a list of possible realms seperated by comma spaces | | | |
| * enclosed by brackets. | | | |
| */ | | | |
| typedef int sasl_getrealm_t(void *context, int id, | | typedef int sasl_getrealm_t(void *context, int id, | |
| const char **availrealms, | | const char **availrealms, | |
| const char **result); | | const char **result); | |
|
| #define SASL_CB_GETREALM (0x4007) /* realm to attempt authentication in */ | | #define SASL_CB_GETREALM (0x4008) /* realm to attempt authentication in */ | |
| | | | |
| /* server callbacks: | | /* server callbacks: | |
| */ | | */ | |
|
| /* callback to verify authorization | | | |
| * requested_user -- the identity/username to authorize | | /* improved callback to verify authorization; | |
| * auth_identity -- the identity associated with the secret | | * canonicalization now handled elsewhere | |
| * if the identity is not in the realm specified in | | * conn -- connection context | |
| * sasl_server_new, it will be of the form user@realm | | * requested_user -- the identity/username to authorize (NUL terminated) | |
| * return: | | * rlen -- length of requested_user | |
| * user -- NULL = requested_user, otherwise canonicalized | | * auth_identity -- the identity associated with the secret (NUL terminat | |
| * errstr -- can be set to error string on failure | | ed) | |
| * returns SASL_OK on success, SASL_BADAUTH or other SASL response on failu | | * alen -- length of auth_identity | |
| re | | * default_realm -- default user realm, as passed to sasl_server_new if | |
| */ | | * urlen -- length of default realm | |
| typedef int sasl_authorize_t(void *context, | | * propctx -- auxiliary properties | |
| const char *auth_identity, | | * returns SASL_OK on success, | |
| const char *requested_user, | | * SASL_NOAUTHZ or other SASL response on failure | |
| const char **user, | | */ | |
| const char **errstr); | | typedef int sasl_authorize_t(sasl_conn_t *conn, | |
| #define SASL_CB_PROXY_POLICY (0x8001) | | void *context, | |
| | | const char *requested_user, unsigned rlen, | |
| /* callback to lookup a user's secret for a mechanism | | const char *auth_identity, unsigned alen, | |
| * mechanism -- the mechanism requesting its secret | | const char *def_realm, unsigned urlen, | |
| * auth_identity -- the identity being looked up | | struct propctx *propctx); | |
| * realm -- the realm the identity is in | | #define SASL_CB_PROXY_POLICY 0x8001 | |
| * return: | | | |
| * secret -- the secret associated with this user | | /* functions for "userdb" based plugins to call to get/set passwords. | |
| * for this mechanism | | * the location for the passwords is determined by the caller or middleware | |
| * returns SASL_OK on success or other SASL response on failure | | . | |
| */ | | * plug-ins may get passwords from other locations. | |
| typedef int sasl_server_getsecret_t(void *context, | | */ | |
| const char *mechanism, | | | |
| const char *auth_identity, | | /* callback to verify a plaintext password against the caller-supplied | |
| const char *realm, | | * user database. This is necessary to allow additional <method>s for | |
| sasl_secret_t ** secret); | | * encoding of the userPassword property. | |
| #define SASL_CB_SERVER_GETSECRET (0x8002) | | * user -- NUL terminated user name with user@realm syntax | |
| | | * pass -- password to check (may not be NUL terminated) | |
| /* callback to store a user's secret for a mechanism | | * passlen -- length of password to check | |
| * mechanism -- the mechanism storing its secret | | * propctx -- auxiliary properties for user | |
| * auth_identity -- the identity being stored | | */ | |
| * realm -- the realm the identity is in | | typedef int sasl_server_userdb_checkpass_t(sasl_conn_t *conn, | |
| * secret -- the secret associated with this user | | void *context, | |
| * for this mechanism. If NULL, user's secret | | const char *user, | |
| * for this mechanism will be erased. | | const char *pass, | |
| * returns SASL_OK on success or other SASL response on failure | | unsigned passlen, | |
| */ | | struct propctx *propctx); | |
| typedef int sasl_server_putsecret_t(void *context, | | #define SASL_CB_SERVER_USERDB_CHECKPASS (0x8005) | |
| const char *mechanism, | | | |
| const char *auth_identity, | | /* callback to store/change a plaintext password in the user database | |
| const char *realm, | | * user -- NUL terminated user name with user@realm syntax | |
| const sasl_secret_t * secret); | | * pass -- password to store (may not be NUL terminated) | |
| #define SASL_CB_SERVER_PUTSECRET (0x8003) | | * passlen -- length of password to store | |
| | | * propctx -- auxiliary properties (not stored) | |
| | | * flags -- see SASL_SET_* flags below (SASL_SET_CREATE optional) | |
| | | */ | |
| | | typedef int sasl_server_userdb_setpass_t(sasl_conn_t *conn, | |
| | | void *context, | |
| | | const char *user, | |
| | | const char *pass, | |
| | | unsigned passlen, | |
| | | struct propctx *propctx, | |
| | | unsigned flags); | |
| | | #define SASL_CB_SERVER_USERDB_SETPASS (0x8006) | |
| | | | |
| | | /* callback for a server-supplied user canonicalization function. | |
| | | * | |
| | | * This function is called directly after the mechanism has the | |
| | | * authentication and authorization IDs. It is called before any | |
| | | * User Canonicalization plugin is called. It has the responsibility | |
| | | * of copying its output into the provided output buffers. | |
| | | * | |
| | | * in, inlen -- user name to canonicalize, may not be NUL terminated | |
| | | * may be same buffer as out | |
| | | * flags -- not currently used, supplied by auth mechanism | |
| | | * user_realm -- the user realm (may be NULL in case of client) | |
| | | * out -- buffer to copy user name | |
| | | * out_max -- max length of user name | |
| | | * out_len -- set to length of user name | |
| | | * | |
| | | * returns | |
| | | * SASL_OK on success | |
| | | * SASL_BADPROT username contains invalid character | |
| | | */ | |
| | | | |
| | | /* User Canonicalization Function Flags */ | |
| | | | |
| | | #define SASL_CU_NONE 0x00 /* Not a valid flag to pass */ | |
| | | /* One of the following two is required */ | |
| | | #define SASL_CU_AUTHID 0x01 | |
| | | #define SASL_CU_AUTHZID 0x02 | |
| | | | |
| | | typedef int sasl_canon_user_t(sasl_conn_t *conn, | |
| | | void *context, | |
| | | const char *in, unsigned inlen, | |
| | | unsigned flags, | |
| | | const char *user_realm, | |
| | | char *out, | |
| | | unsigned out_max, unsigned *out_len); | |
| | | | |
| | | #define SASL_CB_CANON_USER (0x8007) | |
| | | | |
| /********************************** | | /********************************** | |
| * Common Client/server functions * | | * Common Client/server functions * | |
| **********************************/ | | **********************************/ | |
| | | | |
| /* dispose of all SASL plugins. Connection | | /* dispose of all SASL plugins. Connection | |
| * states have to be disposed of before calling this. | | * states have to be disposed of before calling this. | |
| */ | | */ | |
| LIBSASL_API void sasl_done(void); | | LIBSASL_API void sasl_done(void); | |
| | | | |
| /* dispose connection state, sets it to NULL | | /* dispose connection state, sets it to NULL | |
| * checks for pointer to NULL | | * checks for pointer to NULL | |
| */ | | */ | |
| LIBSASL_API void sasl_dispose(sasl_conn_t **pconn); | | LIBSASL_API void sasl_dispose(sasl_conn_t **pconn); | |
| | | | |
|
| /* translate server error code to user error code | | | |
| * currently only maps SASL_NOUSER to SASL_BADAUTH | | | |
| */ | | | |
| LIBSASL_API int sasl_usererr(int saslerr); | | | |
| | | | |
| /* translate an error number into a string | | /* translate an error number into a string | |
| * input: | | * input: | |
| * saslerr -- the error number | | * saslerr -- the error number | |
| * langlist -- comma separated list of RFC 1766 languages (may be NULL) | | * langlist -- comma separated list of RFC 1766 languages (may be NULL) | |
| * results: | | * results: | |
| * outlang -- the language actually used (may be NULL if don't care) | | * outlang -- the language actually used (may be NULL if don't care) | |
| * returns: | | * returns: | |
|
| * the error message | | * the error message in UTF-8 (only the US-ASCII subset if langlist is NUL
L) | |
| */ | | */ | |
| LIBSASL_API const char *sasl_errstring(int saslerr, | | LIBSASL_API const char *sasl_errstring(int saslerr, | |
|
| const char *langlist, | | const char *langlist, | |
| const char **outlang); | | const char **outlang); | |
| | | | |
| | | /* get detail about the last error that occurred on a connection | |
| | | * text is sanitized so it's suitable to send over the wire | |
| | | * (e.g., no distinction between SASL_BADAUTH and SASL_NOUSER) | |
| | | * input: | |
| | | * conn -- mandatory connection context | |
| | | * returns: | |
| | | * the error message in UTF-8 (only the US-ASCII subset permitted if no | |
| | | * SASL_CB_LANGUAGE callback is present) | |
| | | */ | |
| | | LIBSASL_API const char *sasl_errdetail(sasl_conn_t *conn); | |
| | | | |
| | | /* set the error string which will be returned by sasl_errdetail() using | |
| | | * syslog()-style formatting (e.g. printf-style with %m as most recent | |
| | | * errno error) | |
| | | * | |
| | | * primarily for use by server callbacks such as the sasl_authorize_t | |
| | | * callback and internally to plug-ins | |
| | | * | |
| | | * This will also trigger a call to the SASL logging callback (if any) | |
| | | * with a level of SASL_LOG_FAIL unless the SASL_NOLOG flag is set. | |
| | | * | |
| | | * Messages should be sensitive to the current language setting. If there | |
| | | * is no SASL_CB_LANGUAGE callback messages MUST be US-ASCII otherwise UTF- | |
| | | 8 | |
| | | * is used and use of RFC 2482 for mixed-language text is encouraged. | |
| | | * | |
| | | * if conn is NULL, function does nothing | |
| | | */ | |
| | | LIBSASL_API void sasl_seterror(sasl_conn_t *conn, unsigned flags, | |
| | | const char *fmt, ...); | |
| | | #define SASL_NOLOG 0x01 | |
| | | | |
| /* get property from SASL connection state | | /* get property from SASL connection state | |
| * propnum -- property number | | * propnum -- property number | |
| * pvalue -- pointer to value | | * pvalue -- pointer to value | |
| * returns: | | * returns: | |
| * SASL_OK -- no error | | * SASL_OK -- no error | |
| * SASL_NOTDONE -- property not available yet | | * SASL_NOTDONE -- property not available yet | |
| * SASL_BADPARAM -- bad property number | | * SASL_BADPARAM -- bad property number | |
| */ | | */ | |
|
| LIBSASL_API int sasl_getprop(sasl_conn_t *conn, int propnum, void **pvalue) | | LIBSASL_API int sasl_getprop(sasl_conn_t *conn, int propnum, | |
| ; | | const void **pvalue); | |
| #define SASL_USERNAME 0 /* pointer to NUL terminated user name */ | | #define SASL_USERNAME 0 /* pointer to NUL terminated user name */ | |
| #define SASL_SSF 1 /* security layer security strength factor, | | #define SASL_SSF 1 /* security layer security strength factor, | |
| * if 0, call to sasl_encode, sasl_decode | | * if 0, call to sasl_encode, sasl_decode | |
| * unnecessary */ | | * unnecessary */ | |
| #define SASL_MAXOUTBUF 2 /* security layer max output buf unsigned */ | | #define SASL_MAXOUTBUF 2 /* security layer max output buf unsigned * | |
| #define SASL_REALM 3 /* server authentication realm used */ | | / | |
| #define SASL_GETOPTCTX 4 /* context for getopt callback */ | | #define SASL_DEFUSERREALM 3 /* default realm passed to server_new */ | |
| #define SASL_IP_LOCAL 5 /* local address (pvalue=sockaddr_in *) */ | | /* or set with setprop */ | |
| #define SASL_IP_REMOTE 6 /* remote address (pvalue=sockaddr_in *) */ | | #define SASL_GETOPTCTX 4 /* context for getopt callback */ | |
| | | #define SASL_CALLBACK 7 /* current callback function list */ | |
| | | #define SASL_IPLOCALPORT 8 /* iplocalport string passed to server_new * | |
| | | / | |
| | | #define SASL_IPREMOTEPORT 9 /* ipremoteport string passed to server_new | |
| | | */ | |
| | | #define SASL_SERVICE 12 /* service passed to sasl_*_new */ | |
| | | #define SASL_SERVERFQDN 13 /* serverFQDN passed to sasl_*_new */ | |
| | | #define SASL_AUTHSOURCE 14 /* name of auth source last used, useful | |
| | | * for failed authentication tracking */ | |
| | | #define SASL_MECHNAME 15 /* active mechanism name, if any */ | |
| | | | |
| | | /* This returns a string which is either empty or has an error message | |
| | | * from sasl_seterror (e.g., from a plug-in or callback). It differs | |
| | | * from the result of sasl_errdetail() which also takes into account the | |
| | | * last return status code. | |
| | | */ | |
| | | #define SASL_PLUGERR 10 | |
| | | | |
| /* set property in SASL connection state | | /* set property in SASL connection state | |
| * returns: | | * returns: | |
| * SASL_OK -- value set | | * SASL_OK -- value set | |
| * SASL_BADPARAM -- invalid property or value | | * SASL_BADPARAM -- invalid property or value | |
| */ | | */ | |
| LIBSASL_API int sasl_setprop(sasl_conn_t *conn, | | LIBSASL_API int sasl_setprop(sasl_conn_t *conn, | |
| int propnum, | | int propnum, | |
| const void *value); | | const void *value); | |
|
| #define SASL_SSF_EXTERNAL 100 /* external SSF active -- | | #define SASL_SSF_EXTERNAL 100 /* external SSF active (sasl_ssf_t *) */ | |
| * sasl_external_properties_t */ | | #define SASL_SEC_PROPS 101 /* sasl_security_properties_t */ | |
| #define SASL_SEC_PROPS 101 /* sasl_security_properties_t */ | | #define SASL_AUTH_EXTERNAL 102 /* external authentication ID (const char *) | |
| /* also allows SASL_IP_LOCAL, SASL_IP_REMOTE | | */ | |
| */ | | | |
| | | /* If the SASL_AUTH_EXTERNAL value is non-NULL, then a special version of t | |
| | | he | |
| | | * EXTERNAL mechanism is enabled (one for server-embedded EXTERNAL mechanis | |
| | | ms). | |
| | | * Otherwise, the EXTERNAL mechanism will be absent unless a plug-in | |
| | | * including EXTERNAL is present. | |
| | | */ | |
| | | | |
| /* do precalculations during an idle period or network round trip | | /* do precalculations during an idle period or network round trip | |
| * may pass NULL to precompute for some mechanisms prior to connect | | * may pass NULL to precompute for some mechanisms prior to connect | |
| * returns 1 if action taken, 0 if no action taken | | * returns 1 if action taken, 0 if no action taken | |
| */ | | */ | |
| LIBSASL_API int sasl_idle(sasl_conn_t *conn); | | LIBSASL_API int sasl_idle(sasl_conn_t *conn); | |
| | | | |
| /************** | | /************** | |
| * Client API * | | * Client API * | |
| **************/ | | **************/ | |
| | | | |
| /* list of client interactions with user for caller to fill in | | /* list of client interactions with user for caller to fill in | |
| */ | | */ | |
| typedef struct sasl_interact { | | typedef struct sasl_interact { | |
| unsigned long id; /* same as client/user callback ID */ | | unsigned long id; /* same as client/user callback ID */ | |
|
| const char *challenge; /* may be computer readable */ | | const char *challenge; /* presented to user (e.g. OTP challenge) */ | |
| const char *prompt; /* always human readable */ | | const char *prompt; /* presented to user (e.g. "Username | |
| | | : ") */ | |
| const char *defresult; /* default result string */ | | const char *defresult; /* default result string */ | |
|
| void *result; /* set to point to result -- this will | | const void *result; /* set to point to result */ | |
| * be freed by the library iff it | | | |
| * would be freed by the library if | | | |
| * returned from normal callback of | | | |
| * the same id */ | | | |
| unsigned len; /* set to length of result */ | | unsigned len; /* set to length of result */ | |
| } sasl_interact_t; | | } sasl_interact_t; | |
| | | | |
| /* initialize the SASL client drivers | | /* initialize the SASL client drivers | |
|
| * callbacks -- base callbacks for all client connections | | * callbacks -- base callbacks for all client connections; | |
| | | * must include getopt callback | |
| * returns: | | * returns: | |
| * SASL_OK -- Success | | * SASL_OK -- Success | |
| * SASL_NOMEM -- Not enough memory | | * SASL_NOMEM -- Not enough memory | |
| * SASL_BADVERS -- Mechanism version mismatch | | * SASL_BADVERS -- Mechanism version mismatch | |
|
| * SASL_BADPARAM -- error in config file | | * SASL_BADPARAM -- missing getopt callback or error in config file | |
| * SASL_NOMECH -- No mechanisms available | | * SASL_NOMECH -- No mechanisms available | |
| * ... | | * ... | |
| */ | | */ | |
| LIBSASL_API int sasl_client_init(const sasl_callback_t *callbacks); | | LIBSASL_API int sasl_client_init(const sasl_callback_t *callbacks); | |
| | | | |
| /* initialize a client exchange based on the specified mechanism | | /* initialize a client exchange based on the specified mechanism | |
| * service -- registered name of the service using SASL (e.g. "imap"
) | | * service -- registered name of the service using SASL (e.g. "imap"
) | |
| * serverFQDN -- the fully qualified domain name of the server | | * serverFQDN -- the fully qualified domain name of the server | |
|
| | | * iplocalport -- client IPv4/IPv6 domain literal string with port | |
| | | * (if NULL, then mechanisms requiring IPaddr are disabl | |
| | | ed) | |
| | | * ipremoteport -- server IPv4/IPv6 domain literal string with port | |
| | | * (if NULL, then mechanisms requiring IPaddr are disabl | |
| | | ed) | |
| * prompt_supp -- list of client interactions supported | | * prompt_supp -- list of client interactions supported | |
| * may also include sasl_getopt_t context & call | | * may also include sasl_getopt_t context & call | |
| * NULL prompt_supp = user/pass via SASL_INTERACT only | | * NULL prompt_supp = user/pass via SASL_INTERACT only | |
| * NULL proc = interaction supported via SASL_INTERACT | | * NULL proc = interaction supported via SASL_INTERACT | |
|
| * secflags -- security flags (see above) | | * flags -- server usage flags (see above) | |
| * in/out: | | * in/out: | |
| * pconn -- connection negotiation structure | | * pconn -- connection negotiation structure | |
| * pointer to NULL => allocate new | | * pointer to NULL => allocate new | |
| * | | * | |
| * Returns: | | * Returns: | |
| * SASL_OK -- success | | * SASL_OK -- success | |
| * SASL_NOMECH -- no mechanism meets requested properties | | * SASL_NOMECH -- no mechanism meets requested properties | |
| * SASL_NOMEM -- not enough memory | | * SASL_NOMEM -- not enough memory | |
| */ | | */ | |
| LIBSASL_API int sasl_client_new(const char *service, | | LIBSASL_API int sasl_client_new(const char *service, | |
|
| const char *serverFQDN, | | const char *serverFQDN, | |
| const sasl_callback_t *prompt_supp, | | const char *iplocalport, | |
| int secflags, | | const char *ipremoteport, | |
| sasl_conn_t **pconn); | | const sasl_callback_t *prompt_supp, | |
| | | unsigned flags, | |
| | | sasl_conn_t **pconn); | |
| | | | |
| /* select a mechanism for a connection | | /* select a mechanism for a connection | |
| * mechlist -- mechanisms server has available (punctuation ignored) | | * mechlist -- mechanisms server has available (punctuation ignored) | |
|
| * secret -- optional secret from previous session | | * if NULL, then discard cached info and retry last mech | |
| * output: | | * output: | |
| * prompt_need -- on SASL_INTERACT, list of prompts needed to continue | | * prompt_need -- on SASL_INTERACT, list of prompts needed to continue | |
|
| | | * may be NULL if callbacks provided | |
| * clientout -- the initial client response to send to the server | | * clientout -- the initial client response to send to the server | |
|
| * mech -- set to mechanism name | | * will be valid until next call to client_start/client_s | |
| | | tep | |
| | | * NULL if mech doesn't include initial client challenge | |
| | | * mech -- set to mechansm name of selected mechanism (may be NUL | |
| | | L) | |
| * | | * | |
| * Returns: | | * Returns: | |
| * SASL_OK -- success | | * SASL_OK -- success | |
| * SASL_NOMEM -- not enough memory | | * SASL_NOMEM -- not enough memory | |
| * SASL_NOMECH -- no mechanism meets requested properties | | * SASL_NOMECH -- no mechanism meets requested properties | |
| * SASL_INTERACT -- user interaction needed to fill in prompt_need list | | * SASL_INTERACT -- user interaction needed to fill in prompt_need list | |
| */ | | */ | |
| LIBSASL_API int sasl_client_start(sasl_conn_t *conn, | | LIBSASL_API int sasl_client_start(sasl_conn_t *conn, | |
| const char *mechlist, | | const char *mechlist, | |
|
| sasl_secret_t *secret, | | | |
| sasl_interact_t **prompt_need, | | sasl_interact_t **prompt_need, | |
|
| char **clientout, | | const char **clientout, | |
| unsigned *clientoutlen, | | unsigned *clientoutlen, | |
| const char **mech); | | const char **mech); | |
| | | | |
| /* do a single authentication step. | | /* do a single authentication step. | |
| * serverin -- the server message received by the client, MUST have a N
UL | | * serverin -- the server message received by the client, MUST have a N
UL | |
| * sentinel, not counted by serverinlen | | * sentinel, not counted by serverinlen | |
| * output: | | * output: | |
| * prompt_need -- on SASL_INTERACT, list of prompts needed to continue | | * prompt_need -- on SASL_INTERACT, list of prompts needed to continue | |
| * clientout -- the client response to send to the server | | * clientout -- the client response to send to the server | |
|
| | | * will be valid until next call to client_start/client_ste
p | |
| * | | * | |
| * returns: | | * returns: | |
| * SASL_OK -- success | | * SASL_OK -- success | |
| * SASL_INTERACT -- user interaction needed to fill in prompt_need list | | * SASL_INTERACT -- user interaction needed to fill in prompt_need list | |
| * SASL_BADPROT -- server protocol incorrect/cancelled | | * SASL_BADPROT -- server protocol incorrect/cancelled | |
| * SASL_BADSERV -- server failed mutual auth | | * SASL_BADSERV -- server failed mutual auth | |
| */ | | */ | |
|
| LIBSASL_API int | | LIBSASL_API int sasl_client_step(sasl_conn_t *conn, | |
| sasl_client_step(sasl_conn_t *conn, | | const char *serverin, | |
| const char *serverin, | | unsigned serverinlen, | |
| unsigned serverinlen, | | sasl_interact_t **prompt_need, | |
| sasl_interact_t **prompt_need, | | const char **clientout, | |
| char **clientout, | | unsigned *clientoutlen); | |
| unsigned *clientoutlen); | | | |
| | | | |
| /* Set connection secret based on passphrase | | | |
| * may be used in SASL_CB_PASS callback | | | |
| * input: | | | |
| * user -- username | | | |
| * pass -- plaintext passphrase with NUL sentinel | | | |
| * passlen -- 0 = strlen(pass) | | | |
| * out: | | | |
| * prompts -- if non-NULL, SASL_CB_PASS item filled in | | | |
| * keepcopy -- set to copy of secret if non-NULL | | | |
| * returns: | | | |
| * SASL_OK -- success | | | |
| * SASL_NOMEM -- failure | | | |
| */ | | | |
| LIBSASL_API int | | | |
| sasl_client_auth(sasl_conn_t *conn, | | | |
| const char *user, | | | |
| const char *pass, unsigned passlen, | | | |
| sasl_interact_t *prompts, sasl_secret_t **keepcopy); | | | |
| | | | |
| /* erase & dispose of a sasl_secret_t | | | |
| * calls free utility last set by sasl_set_alloc | | | |
| */ | | | |
| LIBSASL_API void sasl_free_secret(sasl_secret_t **); | | | |
| | | | |
| /************** | | /************** | |
| * Server API * | | * Server API * | |
| **************/ | | **************/ | |
| | | | |
| /* initialize server drivers, done once per process | | /* initialize server drivers, done once per process | |
|
| * callbacks -- base callbacks for all server connections | | * callbacks -- callbacks for all server connections; must include | |
| | | * getopt callback | |
| * appname -- name of calling application (for lower level logging) | | * appname -- name of calling application (for lower level logging) | |
| * results: | | * results: | |
| * state -- server state | | * state -- server state | |
| * returns: | | * returns: | |
| * SASL_OK -- success | | * SASL_OK -- success | |
| * SASL_BADPARAM -- error in config file | | * SASL_BADPARAM -- error in config file | |
| * SASL_NOMEM -- memory failure | | * SASL_NOMEM -- memory failure | |
| * SASL_BADVERS -- Mechanism version mismatch | | * SASL_BADVERS -- Mechanism version mismatch | |
| */ | | */ | |
| LIBSASL_API int sasl_server_init(const sasl_callback_t *callbacks, | | LIBSASL_API int sasl_server_init(const sasl_callback_t *callbacks, | |
| const char *appname); | | const char *appname); | |
| | | | |
|
| | | /* IP/port syntax: | |
| | | * a.b.c.d;p where a-d are 0-255 and p is 0-65535 port number | |
| | | . | |
| | | * e:f:g:h:i:j:k:l;p where e-l are 0000-ffff lower-case hexidecimal | |
| | | * e:f:g:h:i:j:a.b.c.d;p alternate syntax for previous | |
| | | * | |
| | | * Note that one or more "0" fields in f-k can be replaced with "::" | |
| | | * Thus: e:f:0000:0000:0000:j:k:l;p | |
| | | * can be abbreviated: e:f::j:k:l;p | |
| | | * | |
| | | * A buffer of size 52 is adequate for the longest format with NUL terminat | |
| | | or. | |
| | | */ | |
| | | | |
| /* create context for a single SASL connection | | /* create context for a single SASL connection | |
| * service -- registered name of the service using SASL (e.g. "imap
") | | * service -- registered name of the service using SASL (e.g. "imap
") | |
|
| * serverFQDN -- Fully qualified server domain name. NULL means use | | * serverFQDN -- Fully qualified domain name of server. NULL means us | |
| * gethostname(). Useful for multi-homed servers. | | e | |
| * user_realm -- permits multiple user domains on server, NULL = defau | | * gethostname() or equivalent. | |
| lt | | * Useful for multi-homed servers. | |
| | | * user_realm -- permits multiple user realms on server, NULL = defaul | |
| | | t | |
| | | * iplocalport -- server IPv4/IPv6 domain literal string with port | |
| | | * (if NULL, then mechanisms requiring IPaddr are disabl | |
| | | ed) | |
| | | * ipremoteport -- client IPv4/IPv6 domain literal string with port | |
| | | * (if NULL, then mechanisms requiring IPaddr are disabl | |
| | | ed) | |
| * callbacks -- callbacks (e.g., authorization, lang, new getopt cont
ext) | | * callbacks -- callbacks (e.g., authorization, lang, new getopt cont
ext) | |
|
| * secflags -- security flags (see above) | | * flags -- usage flags (see above) | |
| * returns: | | * returns: | |
| * pconn -- new connection context | | * pconn -- new connection context | |
| * | | * | |
| * returns: | | * returns: | |
| * SASL_OK -- success | | * SASL_OK -- success | |
| * SASL_NOMEM -- not enough memory | | * SASL_NOMEM -- not enough memory | |
| */ | | */ | |
| LIBSASL_API int sasl_server_new(const char *service, | | LIBSASL_API int sasl_server_new(const char *service, | |
| const char *serverFQDN, | | const char *serverFQDN, | |
| const char *user_realm, | | const char *user_realm, | |
|
| | | const char *iplocalport, | |
| | | const char *ipremoteport, | |
| const sasl_callback_t *callbacks, | | const sasl_callback_t *callbacks, | |
|
| int secflags, | | unsigned flags, | |
| sasl_conn_t **pconn); | | sasl_conn_t **pconn); | |
| | | | |
|
| | | /* Return an array of NUL-terminated strings, terminated by a NULL pointer, | |
| | | * which lists all possible mechanisms that the library can supply | |
| | | * | |
| | | * Returns NULL on failure. */ | |
| | | LIBSASL_API const char ** sasl_global_listmech(void); | |
| | | | |
| /* This returns a list of mechanisms in a NUL-terminated string | | /* This returns a list of mechanisms in a NUL-terminated string | |
|
| | | * conn -- the connection to list mechanisms for (either client | |
| | | * or server) | |
| * user -- restricts mechanisms to those available to that user | | * user -- restricts mechanisms to those available to that user | |
|
| * (may be NULL) | | * (may be NULL, not used for client case) | |
| * prefix -- appended to beginning of result | | * prefix -- appended to beginning of result | |
| * sep -- appended between mechanisms | | * sep -- appended between mechanisms | |
| * suffix -- appended to end of result | | * suffix -- appended to end of result | |
| * results: | | * results: | |
|
| * result -- NUL terminated allocated result, caller must free | | * result -- NUL terminated result which persists until next | |
| | | * call to sasl_listmech for this sasl_conn_t | |
| * plen -- gets length of result (excluding NUL), may be NULL | | * plen -- gets length of result (excluding NUL), may be NULL | |
| * pcount -- gets number of mechanisms, may be NULL | | * pcount -- gets number of mechanisms, may be NULL | |
| * | | * | |
| * returns: | | * returns: | |
| * SASL_OK -- success | | * SASL_OK -- success | |
| * SASL_NOMEM -- not enough memory | | * SASL_NOMEM -- not enough memory | |
| * SASL_NOMECH -- no enabled mechanisms | | * SASL_NOMECH -- no enabled mechanisms | |
| */ | | */ | |
| LIBSASL_API int sasl_listmech(sasl_conn_t *conn, | | LIBSASL_API int sasl_listmech(sasl_conn_t *conn, | |
| const char *user, | | const char *user, | |
| const char *prefix, | | const char *prefix, | |
| const char *sep, | | const char *sep, | |
| const char *suffix, | | const char *suffix, | |
|
| char **result, | | const char **result, | |
| unsigned *plen, | | unsigned *plen, | |
|
| unsigned *pcount); | | int *pcount); | |
| | | | |
| /* start a mechanism exchange within a connection context | | /* start a mechanism exchange within a connection context | |
| * mech -- the mechanism name client requested | | * mech -- the mechanism name client requested | |
|
| * clientin -- client initial response, NULL if empty | | * clientin -- client initial response (NUL terminated), NULL if emp
ty | |
| * clientinlen -- length of initial response | | * clientinlen -- length of initial response | |
| * serverout -- initial server challenge, NULL if done | | * serverout -- initial server challenge, NULL if done | |
|
| | | * (library handles freeing this string) | |
| * serveroutlen -- length of initial server challenge | | * serveroutlen -- length of initial server challenge | |
| * output: | | * output: | |
| * pconn -- the connection negotiation state on success | | * pconn -- the connection negotiation state on success | |
|
| * errstr -- set to string to send to user on failure | | | |
| * | | * | |
|
| * Same returns as sasl_server_step() | | * Same returns as sasl_server_step() or | |
| | | * SASL_NOMECH if mechanism not available. | |
| */ | | */ | |
| LIBSASL_API int sasl_server_start(sasl_conn_t *conn, | | LIBSASL_API int sasl_server_start(sasl_conn_t *conn, | |
| const char *mech, | | const char *mech, | |
| const char *clientin, | | const char *clientin, | |
| unsigned clientinlen, | | unsigned clientinlen, | |
|
| char **serverout, | | const char **serverout, | |
| unsigned *serveroutlen, | | unsigned *serveroutlen); | |
| const char **errstr); | | | |
| | | | |
| /* perform one step of the SASL exchange | | /* perform one step of the SASL exchange | |
| * inputlen & input -- client data | | * inputlen & input -- client data | |
| * NULL on first step if no optional client step | | * NULL on first step if no optional client step | |
| * outputlen & output -- set to the server data to transmit | | * outputlen & output -- set to the server data to transmit | |
| * to the client in the next step | | * to the client in the next step | |
|
| * errstr -- set to a more text error message from | | * (library handles freeing this) | |
| * a lower level mechanism on failure | | | |
| * | | * | |
| * returns: | | * returns: | |
| * SASL_OK -- exchange is complete. | | * SASL_OK -- exchange is complete. | |
| * SASL_CONTINUE -- indicates another step is necessary. | | * SASL_CONTINUE -- indicates another step is necessary. | |
| * SASL_TRANS -- entry for user exists, but not for mechanism | | * SASL_TRANS -- entry for user exists, but not for mechanism | |
| * and transition is possible | | * and transition is possible | |
| * SASL_BADPARAM -- service name needed | | * SASL_BADPARAM -- service name needed | |
| * SASL_BADPROT -- invalid input from client | | * SASL_BADPROT -- invalid input from client | |
| * ... | | * ... | |
| */ | | */ | |
| LIBSASL_API int sasl_server_step(sasl_conn_t *conn, | | LIBSASL_API int sasl_server_step(sasl_conn_t *conn, | |
|
| const char *clientin, | | const char *clientin, | |
| unsigned clientinlen, | | unsigned clientinlen, | |
| char **serverout, | | const char **serverout, | |
| unsigned *serveroutlen, | | unsigned *serveroutlen); | |
| const char **errstr); | | | |
| | | /* check if an apop exchange is valid | |
| | | * (note this is an optional part of the SASL API) | |
| | | * if challenge is NULL, just check if APOP is enabled | |
| | | * inputs: | |
| | | * challenge -- challenge which was sent to client | |
| | | * challen -- length of challenge, 0 = strlen(challenge) | |
| | | * response -- client response, "<user> <digest>" (RFC 1939) | |
| | | * resplen -- length of response, 0 = strlen(response) | |
| | | * returns | |
| | | * SASL_OK -- success | |
| | | * SASL_BADAUTH -- authentication failed | |
| | | * SASL_BADPARAM -- missing challenge | |
| | | * SASL_BADPROT -- protocol error (e.g., response in wrong format) | |
| | | * SASL_NOVERIFY -- user found, but no verifier | |
| | | * SASL_NOMECH -- mechanism not supported | |
| | | * SASL_NOUSER -- user not found | |
| | | */ | |
| | | LIBSASL_API int sasl_checkapop(sasl_conn_t *conn, | |
| | | const char *challenge, unsigned challen, | |
| | | const char *response, unsigned resplen); | |
| | | | |
| /* check if a plaintext password is valid | | /* check if a plaintext password is valid | |
|
| * if user is NULL, check if plaintext is enabled | | * if user is NULL, check if plaintext passwords are enabled | |
| * inputs: | | * inputs: | |
|
| * user -- user to query in current user_realm | | * user -- user to query in current user_domain | |
| * userlen -- length of username, 0 = strlen(user) | | * userlen -- length of username, 0 = strlen(user) | |
| * pass -- plaintext password to check | | * pass -- plaintext password to check | |
| * passlen -- length of password, 0 = strlen(pass) | | * passlen -- length of password, 0 = strlen(pass) | |
| * outputs: | | | |
| * errstr -- set to error message for use in protocols | | | |
| * returns | | * returns | |
|
| * SASL_OK -- success | | * SASL_OK -- success | |
| * SASL_NOMECH -- user found, but no verifier | | * SASL_NOMECH -- mechanism not supported | |
| * SASL_NOUSER -- user not found | | * SASL_NOVERIFY -- user found, but no verifier | |
| | | * SASL_NOUSER -- user not found | |
| */ | | */ | |
| LIBSASL_API int sasl_checkpass(sasl_conn_t *conn, | | LIBSASL_API int sasl_checkpass(sasl_conn_t *conn, | |
|
| const char *user, | | const char *user, unsigned userlen, | |
| unsigned userlen, | | const char *pass, unsigned passlen); | |
| const char *pass, | | | |
| unsigned passlen, | | | |
| const char **errstr); | | | |
| | | | |
| /* check if a user exists on server | | /* check if a user exists on server | |
|
| | | * conn -- connection context | |
| * service -- registered name of the service using SASL (e.g. "imap"
) | | * service -- registered name of the service using SASL (e.g. "imap"
) | |
|
| * user_realm -- permits multiple user domains on server, NULL = defaul
t | | * user_realm -- permits multiple user realms on server, NULL = default | |
| * user -- NUL terminated user name | | * user -- NUL terminated user name | |
| * | | * | |
| * returns: | | * returns: | |
| * SASL_OK -- success | | * SASL_OK -- success | |
| * SASL_DISABLED -- account disabled | | * SASL_DISABLED -- account disabled | |
| * SASL_NOUSER -- user not found | | * SASL_NOUSER -- user not found | |
|
| * SASL_NOMECH -- user found, but no usable mechanism | | * SASL_NOVERIFY -- user found, but no usable mechanism | |
| | | * SASL_NOMECH -- no mechanisms enabled | |
| */ | | */ | |
|
| LIBSASL_API int sasl_user_exists(const char *service, | | LIBSASL_API int sasl_user_exists(sasl_conn_t *conn, | |
| const char *user_realm, | | const char *service, | |
| const char *user); | | const char *user_realm, | |
| | | const char *user); | |
| | | | |
| /* set the password for a user | | /* set the password for a user | |
| * conn -- SASL connection | | * conn -- SASL connection | |
| * user -- user name | | * user -- user name | |
| * pass -- plaintext password, may be NULL to remove user | | * pass -- plaintext password, may be NULL to remove user | |
| * passlen -- length of password, 0 = strlen(pass) | | * passlen -- length of password, 0 = strlen(pass) | |
|
| | | * oldpass -- NULL will sometimes work | |
| | | * oldpasslen -- length of password, 0 = strlen(oldpass) | |
| * flags -- see flags below | | * flags -- see flags below | |
|
| * errstr -- optional more detailed error | | | |
| * | | * | |
| * returns: | | * returns: | |
| * SASL_NOCHANGE -- proper entry already exists | | * SASL_NOCHANGE -- proper entry already exists | |
| * SASL_NOMECH -- no authdb supports password setting as configured | | * SASL_NOMECH -- no authdb supports password setting as configured | |
|
| | | * SASL_NOVERIFY -- user exists, but no settable password present | |
| * SASL_DISABLED -- account disabled | | * SASL_DISABLED -- account disabled | |
| * SASL_PWLOCK -- password locked | | * SASL_PWLOCK -- password locked | |
|
| | | * SASL_WEAKPASS -- password too weak for security policy | |
| | | * SASL_NOUSERPASS -- user-supplied passwords not permitted | |
| * SASL_FAIL -- OS error | | * SASL_FAIL -- OS error | |
| * SASL_BADPARAM -- password too long | | * SASL_BADPARAM -- password too long | |
| * SASL_OK -- successful | | * SASL_OK -- successful | |
| */ | | */ | |
| LIBSASL_API int sasl_setpass(sasl_conn_t *conn, | | LIBSASL_API int sasl_setpass(sasl_conn_t *conn, | |
|
| const char *user, | | const char *user, | |
| const char *pass, | | const char *pass, unsigned passlen, | |
| unsigned passlen, | | const char *oldpass, unsigned oldpasslen, | |
| int flags, | | unsigned flags); | |
| const char **errstr); | | | |
| #define SASL_SET_CREATE 0x01 /* create a new entry for user */ | | #define SASL_SET_CREATE 0x01 /* create a new entry for user */ | |
| #define SASL_SET_DISABLE 0x02 /* disable user account */ | | #define SASL_SET_DISABLE 0x02 /* disable user account */ | |
| | | | |
|
| | | /********************************************************* | |
| | | * Auxiliary Property Support -- added by cjn 1999-09-29 * | |
| | | *********************************************************/ | |
| | | | |
| | | #define SASL_AUX_END NULL /* last auxiliary property */ | |
| | | | |
| | | /* traditional Posix items (should be implemented on Posix systems) */ | |
| | | #define SASL_AUX_PASSWORD "userPassword" /* User Password */ | |
| | | #define SASL_AUX_UIDNUM "uidNumber" /* UID number for the user */ | |
| | | #define SASL_AUX_GIDNUM "gidNumber" /* GID for the user */ | |
| | | #define SASL_AUX_FULLNAME "gecos" /* full name of the user, unix-style | |
| | | */ | |
| | | #define SASL_AUX_HOMEDIR "homeDirectory" /* home directory for user */ | |
| | | #define SASL_AUX_SHELL "loginShell" /* login shell for the user */ | |
| | | | |
| | | /* optional additional items (not necessarily implemented) */ | |
| | | /* single preferred mail address for user canonically-quoted | |
| | | * RFC821/822 syntax */ | |
| | | #define SASL_AUX_MAILADDR "mail" | |
| | | /* path to unix-style mailbox for user */ | |
| | | #define SASL_AUX_UNIXMBX "mailMessageStore" | |
| | | /* SMTP mail channel name to use if user authenticates successfully */ | |
| | | #define SASL_AUX_MAILCHAN "mailSMTPSubmitChannel" | |
| | | | |
| | | /* Request a set of auxiliary properties | |
| | | * conn connection context | |
| | | * propnames list of auxiliary property names to request ending with | |
| | | * NULL. | |
| | | * | |
| | | * Subsequent calls will add items to the request list. Call with NULL | |
| | | * to clear the request list. | |
| | | * | |
| | | * errors | |
| | | * SASL_OK -- success | |
| | | * SASL_BADPARAM -- bad count/conn parameter | |
| | | * SASL_NOMEM -- out of memory | |
| | | */ | |
| | | LIBSASL_API int sasl_auxprop_request(sasl_conn_t *conn, | |
| | | const char **propnames); | |
| | | | |
| | | /* Returns current auxiliary property context. | |
| | | * Use functions in prop.h to access content | |
| | | * | |
| | | * if authentication hasn't completed, property values may be empty/NULL | |
| | | * | |
| | | * properties not recognized by active plug-ins will be left empty/NULL | |
| | | * | |
| | | * returns NULL if conn is invalid. | |
| | | */ | |
| | | LIBSASL_API struct propctx *sasl_auxprop_getctx(sasl_conn_t *conn); | |
| | | | |
| /********************** | | /********************** | |
| * security layer API * | | * security layer API * | |
| **********************/ | | **********************/ | |
| | | | |
|
| /* encode a block of data for transmission using security layer | | /* encode a block of data for transmission using security layer, | |
| | | * returning the input buffer if there is no security layer. | |
| | | * output is only valid until next call to sasl_encode or sasl_encodev | |
| * returns: | | * returns: | |
| * SASL_OK -- success (returns input if no layer negotiated) | | * SASL_OK -- success (returns input if no layer negotiated) | |
| * SASL_NOTDONE -- security layer negotiation not finished | | * SASL_NOTDONE -- security layer negotiation not finished | |
|
| | | * SASL_BADPARAM -- inputlen is greater than the SASL_MAXOUTBUF | |
| */ | | */ | |
| LIBSASL_API int sasl_encode(sasl_conn_t *conn, | | LIBSASL_API int sasl_encode(sasl_conn_t *conn, | |
| const char *input, unsigned inputlen, | | const char *input, unsigned inputlen, | |
|
| char **output, unsigned *outputlen); | | const char **output, unsigned *outputlen); | |
| | | | |
|
| /* decode a block of data received using security layer | | /* encode a block of data for transmission using security layer | |
| | | * output is only valid until next call to sasl_encode or sasl_encodev | |
| * returns: | | * returns: | |
| * SASL_OK -- success (returns input if no layer negotiated) | | * SASL_OK -- success (returns input if no layer negotiated) | |
| * SASL_NOTDONE -- security layer negotiation not finished | | * SASL_NOTDONE -- security layer negotiation not finished | |
|
| | | * SASL_BADPARAM -- input length is greater than the SASL_MAXOUTBUF | |
| | | * or no security layer | |
| */ | | */ | |
|
| LIBSASL_API int sasl_decode(sasl_conn_t *conn, | | LIBSASL_API int sasl_encodev(sasl_conn_t *conn, | |
| const char *input, unsigned inputlen, | | const struct iovec *invec, unsigned numiov, | |
| char **output, unsigned *outputlen); | | const char **output, unsigned *outputlen); | |
| | | | |
|
| /************************************ | | /* decode a block of data received using security layer | |
| * Credentials API (used by server) * | | * returning the input buffer if there is no security layer. | |
| ************************************/ | | * output is only valid until next call to sasl_decode | |
| | | | |
| /* install credentials passed by the client | | | |
| * Installing a set of credentials may install them on a per-process | | | |
| * or a per-thread basis; neither behavior may be assumed. | | | |
| * returns: | | * returns: | |
|
| * SASL_OK -- success | | * SASL_OK -- success (returns input if no layer negotiated) | |
| * SASL_FAIL -- failure | | * SASL_NOTDONE -- security layer negotiation not finished | |
| * SASL_NOTDONE -- credentials not passed | | * SASL_BADMAC -- bad message integrity check | |
| */ | | */ | |
|
| LIBSASL_API int sasl_cred_install(sasl_conn_t *conn); | | LIBSASL_API int sasl_decode(sasl_conn_t *conn, | |
| | | const char *input, unsigned inputlen, | |
| | | const char **output, unsigned *outputlen); | |
| | | | |
|
| /* uninstalls a connection's credentials | | | |
| * returns: | | | |
| * SASL_OK -- success | | | |
| * SASL_FAIL -- failure | | | |
| */ | | | |
| LIBSASL_API int sasl_cred_uninstall(sasl_conn_t *conn); | | | |
| #endif /* SASL_H */ | | #endif /* SASL_H */ | |
| | | | |
End of changes. 125 change blocks. |
| 358 lines changed or deleted | | 578 lines changed or added | |
|
| saslplug.h | | saslplug.h | |
| | | | |
| skipping to change at line 16 | | skipping to change at line 16 | |
| | | | |
| #ifndef MD5GLOBAL_H | | #ifndef MD5GLOBAL_H | |
| #include "md5global.h" | | #include "md5global.h" | |
| #endif | | #endif | |
| #ifndef MD5_H | | #ifndef MD5_H | |
| #include "md5.h" | | #include "md5.h" | |
| #endif | | #endif | |
| #ifndef HMAC_MD5_H | | #ifndef HMAC_MD5_H | |
| #include "hmac-md5.h" | | #include "hmac-md5.h" | |
| #endif | | #endif | |
|
| | | #ifndef PROP_H | |
| | | #include "prop.h" | |
| | | #endif | |
| | | | |
|
| /* callback to lookup a property from a SASL connection state | | /* callback to lookup a sasl_callback_t for a connection | |
| * input: | | | |
| * conn -- the connection to get a property from | | | |
| * propnum -- property number | | | |
| * output: | | | |
| * pvalue -- pointer to value | | | |
| * returns: | | | |
| * SASL_OK -- no error | | | |
| * SASL_NOTDONE -- property not available yet | | | |
| * SASL_BADPARAM -- bad property number | | | |
| */ | | | |
| typedef int sasl_getprop_t(sasl_conn_t *conn, | | | |
| int propnum, | | | |
| void **pvalue); | | | |
| | | | |
| /* callback to lookup a sasl_callback_t for a connnection | | | |
| * input: | | * input: | |
| * conn -- the connection to lookup a callback for | | * conn -- the connection to lookup a callback for | |
| * callbacknum -- the number of the callback | | * callbacknum -- the number of the callback | |
| * output: | | * output: | |
|
| * pproc -- pointer to the callback function | | * pproc -- pointer to the callback function (set to NULL on failure | |
| * pcontext -- pointer to the callback context | | ) | |
| | | * pcontext -- pointer to the callback context (set to NULL on failure) | |
| * returns: | | * returns: | |
| * SASL_OK -- no error | | * SASL_OK -- no error | |
| * SASL_FAIL -- unable to find a callback of the requested type | | * SASL_FAIL -- unable to find a callback of the requested type | |
| * SASL_INTERACT -- caller must use interaction to get data | | * SASL_INTERACT -- caller must use interaction to get data | |
| */ | | */ | |
| typedef int sasl_getcallback_t(sasl_conn_t *conn, | | typedef int sasl_getcallback_t(sasl_conn_t *conn, | |
| unsigned long callbackid, | | unsigned long callbackid, | |
| int (**pproc)(), | | int (**pproc)(), | |
| void **pcontext); | | void **pcontext); | |
| | | | |
|
| #ifdef WIN32 | | /* The sasl_utils structure will remain backwards compatible unless | |
| /* need to handle the fact that errno has been defined as a function | | * the SASL_*_PLUG_VERSION is changed incompatibly | |
| in a dll, not an extern int */ | | * higher SASL_UTILS_VERSION numbers indicate more functions are available | |
| #ifdef errno | | */ | |
| #undef errno | | #define SASL_UTILS_VERSION 4 | |
| #endif /* errno */ | | | |
| #endif /* WIN32 */ | | | |
| | | | |
| /* utility function set for plug-ins | | /* utility function set for plug-ins | |
| */ | | */ | |
| typedef struct sasl_utils { | | typedef struct sasl_utils { | |
| int version; | | int version; | |
| | | | |
| /* contexts */ | | /* contexts */ | |
| sasl_conn_t *conn; | | sasl_conn_t *conn; | |
| sasl_rand_t *rpool; | | sasl_rand_t *rpool; | |
| void *getopt_context; | | void *getopt_context; | |
| | | | |
| /* option function */ | | /* option function */ | |
| sasl_getopt_t *getopt; | | sasl_getopt_t *getopt; | |
| | | | |
|
| /* property function */ | | | |
| sasl_getprop_t *getprop; | | | |
| | | | |
| /* allocation functions: */ | | /* allocation functions: */ | |
| sasl_malloc_t *malloc; | | sasl_malloc_t *malloc; | |
| sasl_calloc_t *calloc; | | sasl_calloc_t *calloc; | |
| sasl_realloc_t *realloc; | | sasl_realloc_t *realloc; | |
| sasl_free_t *free; | | sasl_free_t *free; | |
| | | | |
| /* mutex functions: */ | | /* mutex functions: */ | |
|
| sasl_mutex_new_t *mutex_new; | | sasl_mutex_alloc_t *mutex_alloc; | |
| sasl_mutex_lock_t *mutex_lock; | | sasl_mutex_lock_t *mutex_lock; | |
| sasl_mutex_unlock_t *mutex_unlock; | | sasl_mutex_unlock_t *mutex_unlock; | |
|
| sasl_mutex_dispose_t *mutex_dispose; | | sasl_mutex_free_t *mutex_free; | |
| | | | |
| /* MD5 hash and HMAC functions */ | | /* MD5 hash and HMAC functions */ | |
| void (*MD5Init)(MD5_CTX *); | | void (*MD5Init)(MD5_CTX *); | |
| void (*MD5Update)(MD5_CTX *, const unsigned char *text, unsigned int le
n); | | void (*MD5Update)(MD5_CTX *, const unsigned char *text, unsigned int le
n); | |
| void (*MD5Final)(unsigned char [16], MD5_CTX *); | | void (*MD5Final)(unsigned char [16], MD5_CTX *); | |
| void (*hmac_md5)(const unsigned char *text, int text_len, | | void (*hmac_md5)(const unsigned char *text, int text_len, | |
|
| const unsigned char *key, int key_len, | | const unsigned char *key, int key_len, | |
| unsigned char [16]); | | unsigned char [16]); | |
| void (*hmac_md5_init)(HMAC_MD5_CTX *, const unsigned char *key, int len
); | | void (*hmac_md5_init)(HMAC_MD5_CTX *, const unsigned char *key, int len
); | |
| /* hmac_md5_update() is just a call to MD5Update on inner context */ | | /* hmac_md5_update() is just a call to MD5Update on inner context */ | |
| void (*hmac_md5_final)(unsigned char [16], HMAC_MD5_CTX *); | | void (*hmac_md5_final)(unsigned char [16], HMAC_MD5_CTX *); | |
|
| void (*hmac_md5_precalc)(HMAC_MD5_STATE *, const unsigned char *key, | | void (*hmac_md5_precalc)(HMAC_MD5_STATE *, | |
| int len); | | const unsigned char *key, int len); | |
| void (*hmac_md5_import)(HMAC_MD5_CTX *, HMAC_MD5_STATE *); | | void (*hmac_md5_import)(HMAC_MD5_CTX *, HMAC_MD5_STATE *); | |
| | | | |
| /* mechanism utility functions (same as above): */ | | /* mechanism utility functions (same as above): */ | |
|
| int (*mkchal)(sasl_conn_t *conn, char *buf, unsigned maxlen, int hostfl | | int (*mkchal)(sasl_conn_t *conn, char *buf, unsigned maxlen, | |
| ag); | | unsigned hostflag); | |
| int (*utf8verify)(const char *str, unsigned len); | | int (*utf8verify)(const char *str, unsigned len); | |
| void (*rand)(sasl_rand_t *rpool, char *buf, unsigned len); | | void (*rand)(sasl_rand_t *rpool, char *buf, unsigned len); | |
| void (*churn)(sasl_rand_t *rpool, const char *data, unsigned len); | | void (*churn)(sasl_rand_t *rpool, const char *data, unsigned len); | |
| | | | |
|
| /* current CMU hack. DO NOT USE EXCEPT IN PLAIN */ | | /* This allows recursive calls to the sasl_checkpass() routine from | |
| | | * within a SASL plug-in. This MUST NOT be used in the PLAIN mechanism | |
| | | * as sasl_checkpass MAY be a front-end for the PLAIN mechanism. | |
| | | * This is intended for use by the non-standard LOGIN mechanism and | |
| | | * potentially by a future mechanism which uses public-key technology t | |
| | | o | |
| | | * set up a lightweight encryption layer just for sending a password. | |
| | | */ | |
| int (*checkpass)(sasl_conn_t *conn, | | int (*checkpass)(sasl_conn_t *conn, | |
|
| const char *mech, const char *service, | | const char *user, unsigned userlen, | |
| const char *user, const char *pass, | | const char *pass, unsigned passlen); | |
| const char **errstr); | | | |
| | | /* Access to base64 encode/decode routines */ | |
| | | int (*decode64)(const char *in, unsigned inlen, | |
| | | char *out, unsigned outmax, unsigned *outlen); | |
| | | int (*encode64)(const char *in, unsigned inlen, | |
| | | char *out, unsigned outmax, unsigned *outlen); | |
| | | | |
| | | /* erase a buffer */ | |
| | | void (*erasebuffer)(char *buf, unsigned len); | |
| | | | |
| | | /* callback to sasl_getprop() and sasl_setprop() */ | |
| | | int (*getprop)(sasl_conn_t *conn, int propnum, const void **pvalue); | |
| | | int (*setprop)(sasl_conn_t *conn, int propnum, const void *value); | |
| | | | |
| /* callback function */ | | /* callback function */ | |
| sasl_getcallback_t *getcallback; | | sasl_getcallback_t *getcallback; | |
| | | | |
|
| /* logging */ | | /* format a message and then pass it to the SASL_CB_LOG callback | |
| int (*log)(sasl_conn_t *conn, | | * | |
| int priority, | | * use syslog()-style formatting (printf with %m as most recent errno | |
| const char *plugin_name, | | * error). The implementation may use a fixed size buffer not smaller | |
| int sasl_error, /* %z */ | | * than 512 octets if it securely truncates the message. | |
| int errno, /* %m */ | | * | |
| const char *format, | | * level is a SASL_LOG_* level (see sasl.h) | |
| ...); | | */ | |
| | | void (*log)(sasl_conn_t *conn, int level, const char *fmt, ...); | |
| | | | |
| | | /* callback to sasl_seterror() */ | |
| | | void (*seterror)(sasl_conn_t *conn, unsigned flags, const char *fmt, .. | |
| | | .); | |
| | | | |
| | | /* spare function pointer */ | |
| | | int *(*spare_fptr)(); | |
| | | | |
| | | /* auxiliary property utilities */ | |
| | | struct propctx *(*prop_new)(unsigned estimate); | |
| | | int (*prop_dup)(struct propctx *src_ctx, struct propctx **dst_ctx); | |
| | | int (*prop_request)(struct propctx *ctx, const char **names); | |
| | | const struct propval *(*prop_get)(struct propctx *ctx); | |
| | | int (*prop_getnames)(struct propctx *ctx, const char **names, | |
| | | struct propval *vals); | |
| | | void (*prop_clear)(struct propctx *ctx, int requests); | |
| | | void (*prop_dispose)(struct propctx **ctx); | |
| | | int (*prop_format)(struct propctx *ctx, const char *sep, int seplen, | |
| | | char *outbuf, unsigned outmax, unsigned *outlen); | |
| | | int (*prop_set)(struct propctx *ctx, const char *name, | |
| | | const char *value, int vallen); | |
| | | int (*prop_setvals)(struct propctx *ctx, const char *name, | |
| | | const char **values); | |
| | | void (*prop_erase)(struct propctx *ctx, const char *name); | |
| | | | |
| | | /* for additions which don't require a version upgrade; set to 0 */ | |
| | | int (*spare_fptr1)(); | |
| | | int (*spare_fptr2)(); | |
| | | int (*spare_fptr3)(); | |
| } sasl_utils_t; | | } sasl_utils_t; | |
| | | | |
|
| /* variable sized secret structure created by client mechanism | | /* | |
| * | | * output parameters from SASL API | |
| * structure uses offsets to allow it to be copied & saved | | | |
| * | | * | |
|
| * buf contains the mechanism specific data followed by the mechanism | | * created / destroyed by the glue code, though probably filled in | |
| * name (NUL terminated) followed by the user name (NUL terminated) | | * by a combination of the plugin, the glue code, and the canon_user callba | |
| * mechoffset is offset in buf to start of mechanism name (0 = plain mech) | | ck. | |
| * useroffset is offset in buf to start of user name | | | |
| * | | * | |
|
| * PLAIN: | | | |
| * len = passlen + userlen + 2 | | | |
| * mechoffset = 0 | | | |
| * useroffset = passlen + 1 | | | |
| * <password> NUL | | | |
| * <username> NUL | | | |
| * CRAM-MD5/SCRAM-MD5: | | | |
| * len = userlen + 50 | | | |
| * mechoffset = 32 | | | |
| * useroffset = 41 | | | |
| * <HMAC-MD5 pre-result, big-endian> | | | |
| * "CRAM-MD5" NUL | | | |
| * <username> NUL | | | |
| */ | | | |
| typedef struct sasl_mech_secret { | | | |
| unsigned long len; | | | |
| unsigned long mechoffset; /* 0 if plain mechanism */ | | | |
| unsigned long useroffset; | | | |
| char buf[1]; | | | |
| } sasl_mech_secret_t; | | | |
| | | | |
| typedef struct sasl_credentials sasl_credentials_t; | | | |
| | | | |
| /* output parameters from SASL API | | | |
| */ | | */ | |
| typedef struct sasl_out_params { | | typedef struct sasl_out_params { | |
|
| int doneflag; /* exchange complete */ | | unsigned doneflag; /* exchange complete */ | |
| sasl_ssf_t mech_ssf; /* security layer strength factor of mech */ | | | |
| unsigned maxoutbuf; /* max plain output to security laye | | const char *user; /* canonicalized user name */ | |
| r */ | | const char *authid; /* canonicalized authentication id * | |
| | | / | |
| /* mic functions differs from encode in that the output is intended to | | | |
| be | | unsigned ulen; /* length of canonicalized user name */ | |
| * appended to the input rather than an encapsulated variant of it. | | unsigned alen; /* length of canonicalized authid */ | |
| * a plugin which supports getmic()/verifymic() but not | | | |
| * encode()/decode() should be exportable. Ditto for framework. | | /* security layer information */ | |
| * datalen param of verifymic returns length of data in buffer | | unsigned maxoutbuf; | |
| */ | | sasl_ssf_t mech_ssf; /* Should be set non-zero if negotiation of a | |
| | | * security layer was *attempted*, even if | |
| | | * the negotiation failed */ | |
| void *encode_context; | | void *encode_context; | |
|
| int (*encode)(void *context, const char *input, unsigned inputlen, | | int (*encode)(void *context, const struct iovec *invec, unsigned numiov | |
| char **output, unsigned *outputlen); | | , | |
| int (*getmic)(void *context, const char *input, unsigned inputlen, | | const char **output, unsigned *outputlen); | |
| char **output, unsigned *outputlen); | | | |
| void *decode_context; | | void *decode_context; | |
| int (*decode)(void *context, const char *input, unsigned inputlen, | | int (*decode)(void *context, const char *input, unsigned inputlen, | |
|
| char **output, unsigned *outputlen); | | const char **output, unsigned *outputlen); | |
| int (*verifymic)(void *context, const char *input, unsigned inputlen, | | | |
| unsigned *datalen); | | /* for additions which don't require a version upgrade; set to 0 */ | |
| | | void *spare_ptr1; | |
| char *user; /* canonicalized user name */ | | void *spare_ptr2; | |
| char *authid; /* canonicalized authentication id */ | | void *spare_ptr3; | |
| char *realm; /* security realm */ | | void *spare_ptr4; | |
| | | int (*spare_fptr1)(); | |
| | | int (*spare_fptr2)(); | |
| | | int spare_int1; | |
| | | int spare_int2; | |
| | | int spare_int3; | |
| | | int spare_int4; | |
| | | | |
| /* set to 0 initially, this allows a plugin with extended parameters | | /* set to 0 initially, this allows a plugin with extended parameters | |
| * to work with an older framework by updating version as parameters | | * to work with an older framework by updating version as parameters | |
| * are added. | | * are added. | |
| */ | | */ | |
| int param_version; | | int param_version; | |
|
| | | | |
| /* Credentials passed by clients. NOTE: this should ONLY | | | |
| * be set by server plugins. */ | | | |
| sasl_credentials_t *credentials; | | | |
| } sasl_out_params_t; | | } sasl_out_params_t; | |
| | | | |
| /****************************** | | /****************************** | |
| * Client Mechanism Functions * | | * Client Mechanism Functions * | |
| ******************************/ | | ******************************/ | |
| | | | |
|
| /* input parameters to client SASL plugin | | /* | |
| | | * input parameters to client SASL plugin | |
| | | * | |
| | | * created / destroyed by the glue code | |
| | | * | |
| */ | | */ | |
| typedef struct sasl_client_params { | | typedef struct sasl_client_params { | |
|
| const char *service; /* service name */ | | const char *service; /* service name */ | |
| const char *pass; /* plaintext passphrase, if used */ | | const char *serverFQDN; /* server fully qualified domain name */ | |
| const char *serverFQDN; /* server fully qualified domain name */ | | const char *clientFQDN; /* client's fully qualified domain name */ | |
| const char *clientFQDN; /* client's local domain name */ | | const sasl_utils_t *utils; /* SASL API utility routines -- | |
| sasl_utils_t *utils; /* SASL API utility routines */ | | * for a particular sasl_conn_t, | |
| sasl_mech_secret_t *secret; /* mech-specific decrypted secret | | * MUST remain valid until mech_free is | |
| */ | | * called */ | |
| | | const sasl_callback_t *prompt_supp; /* client callback list */ | |
| | | const char *iplocalport; /* server IP domain literal & port */ | |
| | | const char *ipremoteport; /* client IP domain literal & port */ | |
| | | | |
| | | unsigned servicelen; /* length of service */ | |
| | | unsigned slen; /* length of serverFQDN */ | |
| | | unsigned clen; /* length of clientFQDN */ | |
| | | unsigned iploclen; /* length of iplocalport */ | |
| | | unsigned ipremlen; /* length of ipremoteport */ | |
| | | | |
| /* application's security requirements & info */ | | /* application's security requirements & info */ | |
| sasl_security_properties_t props; | | sasl_security_properties_t props; | |
| sasl_ssf_t external_ssf; /* external SSF active */ | | sasl_ssf_t external_ssf; /* external SSF active */ | |
| | | | |
|
| | | /* for additions which don't require a version upgrade; set to 0 */ | |
| | | void *spare_ptr1; | |
| | | void *spare_ptr2; | |
| | | void *spare_ptr3; | |
| | | void *spare_ptr4; | |
| | | | |
| | | /* Canonicalize a user name from on-wire to internal format | |
| | | * added rjs3 2001-05-23 | |
| | | * Must be called once user name aquired if canon_user is non-NULL. | |
| | | * conn connection context | |
| | | * in user name from wire protocol (need not be NUL terminate | |
| | | d) | |
| | | * len length of user name from wire protocol (0 = strlen(user | |
| | | )) | |
| | | * flags for SASL_CU_* flags | |
| | | * oparams the user, authid, ulen, alen, fields are | |
| | | * set appropriately after canonicalization/copying and | |
| | | * authorization of arguments | |
| | | * | |
| | | * responsible for setting user, ulen, authid, and alen in the oparams | |
| | | * structure | |
| | | * | |
| | | * default behavior is to strip leading and trailing whitespace, as | |
| | | * well as allocating space for and copying the parameters. | |
| | | * | |
| | | * results: | |
| | | * SASL_OK -- success | |
| | | * SASL_NOMEM -- out of memory | |
| | | * SASL_BADPARAM -- invalid conn | |
| | | * SASL_BADPROT -- invalid user/authid | |
| | | */ | |
| | | int (*canon_user)(sasl_conn_t *conn, | |
| | | const char *in, unsigned len, | |
| | | unsigned flags, | |
| | | sasl_out_params_t *oparams); | |
| | | | |
| | | int (*spare_fptr1)(); | |
| | | | |
| | | int spare_int1; | |
| | | int spare_int2; | |
| | | int spare_int3; | |
| | | | |
| | | /* flags field as passed to sasl_client_new */ | |
| | | unsigned flags; | |
| | | | |
| /* set to 0 initially, this allows a plugin with extended parameters | | /* set to 0 initially, this allows a plugin with extended parameters | |
| * to work with an older framework by updating version as parameters | | * to work with an older framework by updating version as parameters | |
| * are added. | | * are added. | |
| */ | | */ | |
| int param_version; | | int param_version; | |
| } sasl_client_params_t; | | } sasl_client_params_t; | |
| | | | |
|
| | | /* features shared between client and server */ | |
| | | /* These allow the glue code to handle client-first and server-last issues | |
| | | */ | |
| | | | |
| | | /* This indicates that the mechanism prefers to do client-send-first | |
| | | * if the protocol allows it. */ | |
| | | #define SASL_FEAT_WANT_CLIENT_FIRST 0x0002 | |
| | | | |
| | | /* This feature is deprecated, instead, plugins should set *serverout to | |
| | | * non-NULL and return SASL_OK intelligently to allow flexible use of | |
| | | * server-last semantics */ | |
| | | /* #define SASL_FEAT_WANT_SERVER_LAST 0x0004 */ | |
| | | | |
| | | /* This feature is deprecated, instead plugins should correctly set | |
| | | * SASL_FEAT_SERVER_FIRST as needed */ | |
| | | /* #define SASL_FEAT_INTERNAL_CLIENT_FIRST 0x0008 */ | |
| | | | |
| | | /* This indicates that the plugin is server-first only. | |
| | | * Not defining either of SASL_FEAT_SERVER_FIRST or | |
| | | * SASL_FEAT_WANT_CLIENT_FIRST indicates that the mechanism will take care | |
| | | * of the client-first situation internally. | |
| | | */ | |
| | | #define SASL_FEAT_SERVER_FIRST 0x0010 | |
| | | | |
| | | /* client plug-in features */ | |
| | | #define SASL_FEAT_NEEDSERVERFQDN 0x0001 | |
| | | | |
| /* a C object for a client mechanism | | /* a C object for a client mechanism | |
| */ | | */ | |
| typedef struct sasl_client_plug { | | typedef struct sasl_client_plug { | |
| /* mechanism name */ | | /* mechanism name */ | |
| const char *mech_name; | | const char *mech_name; | |
| | | | |
| /* best mech additional security layer strength factor */ | | /* best mech additional security layer strength factor */ | |
| sasl_ssf_t max_ssf; | | sasl_ssf_t max_ssf; | |
| | | | |
| /* best security flags, as defined in sasl_security_properties_t */ | | /* best security flags, as defined in sasl_security_properties_t */ | |
|
| int security_flags; | | unsigned security_flags; | |
| | | | |
| | | /* features of plugin */ | |
| | | unsigned features; | |
| | | | |
| /* required prompt ids, NULL = user/pass only */ | | /* required prompt ids, NULL = user/pass only */ | |
|
| const long *required_prompts; | | const unsigned long *required_prompts; | |
| | | | |
| /* global state for mechanism */ | | /* global state for mechanism */ | |
| void *glob_context; | | void *glob_context; | |
| | | | |
| /* create context for mechanism, using params supplied | | /* create context for mechanism, using params supplied | |
| * glob_context -- from above | | * glob_context -- from above | |
| * params -- params from sasl_client_new | | * params -- params from sasl_client_new | |
| * conn_context -- context for one connection | | * conn_context -- context for one connection | |
| * returns: | | * returns: | |
| * SASL_OK -- success | | * SASL_OK -- success | |
| * SASL_NOMEM -- not enough memory | | * SASL_NOMEM -- not enough memory | |
| * SASL_WRONGMECH -- mech doesn't support security params | | * SASL_WRONGMECH -- mech doesn't support security params | |
| */ | | */ | |
| int (*mech_new)(void *glob_context, | | int (*mech_new)(void *glob_context, | |
|
| sasl_client_params_t *params, | | sasl_client_params_t *cparams, | |
| void **conn_context); | | void **conn_context); | |
| | | | |
| /* perform one step of exchange. NULL is passed for serverin on | | /* perform one step of exchange. NULL is passed for serverin on | |
| * first step. | | * first step. | |
| * returns: | | * returns: | |
| * SASL_OK -- success | | * SASL_OK -- success | |
| * SASL_INTERACT -- user interaction needed to fill in prompts | | * SASL_INTERACT -- user interaction needed to fill in prompts | |
| * SASL_BADPROT -- server protocol incorrect/cancelled | | * SASL_BADPROT -- server protocol incorrect/cancelled | |
| * SASL_BADSERV -- server failed mutual auth | | * SASL_BADSERV -- server failed mutual auth | |
| */ | | */ | |
| int (*mech_step)(void *conn_context, | | int (*mech_step)(void *conn_context, | |
|
| sasl_client_params_t *params, | | sasl_client_params_t *cparams, | |
| const char *serverin, | | const char *serverin, | |
| int serverinlen, | | unsigned serverinlen, | |
| sasl_interact_t **prompt_need, | | sasl_interact_t **prompt_need, | |
|
| char **clientout, | | const char **clientout, | |
| int *clientoutlen, | | unsigned *clientoutlen, | |
| sasl_out_params_t *oparams); | | sasl_out_params_t *oparams); | |
| | | | |
| /* dispose of connection context from mech_new | | /* dispose of connection context from mech_new | |
| */ | | */ | |
|
| void (*mech_dispose)(void *conn_context, sasl_utils_t *utils); | | void (*mech_dispose)(void *conn_context, const sasl_utils_t *utils); | |
| | | | |
| /* free all global space used by mechanism | | /* free all global space used by mechanism | |
| * mech_dispose must be called on all mechanisms first | | * mech_dispose must be called on all mechanisms first | |
| */ | | */ | |
|
| void (*mech_free)(void *glob_context, sasl_utils_t *utils); | | void (*mech_free)(void *glob_context, const sasl_utils_t *utils); | |
| | | | |
|
| /* create an authentication secret (optional) | | /* perform precalculations during a network round-trip | |
| * glob_context -- from above | | * or idle period. conn_context may be NULL | |
| * user -- user name | | * returns 1 if action taken, 0 if no action taken | |
| * pass -- password/passphrase | | */ | |
| * passlen -- length of password/passphrase | | int (*idle)(void *glob_context, | |
| * prompts -- prompts result list, from mech_new or middleware | | void *conn_context, | |
| * utils -- middleware utilities (e.g., MD5, SHA-1) | | sasl_client_params_t *cparams); | |
| * output: | | | |
| * psecret -- gets unencrypted secret | | /* for additions which don't require a version upgrade; set to 0 */ | |
| * | | int (*spare_fptr1)(); | |
| * returns: | | int (*spare_fptr2)(); | |
| * SASL_INTERACT -- not enough of prompts supplied | | | |
| * SASL_OK -- success | | | |
| * SASL_BADPARAM -- wrong prompts supplied | | | |
| * SASL_NOMEM -- out of memory | | | |
| * SASL_NOMECH -- missing utility functions | | | |
| */ | | | |
| int (*auth_create)(void *glob_context, | | | |
| const char *user, | | | |
| const char *pass, | | | |
| int passlen, | | | |
| sasl_interact_t *prompts, | | | |
| sasl_utils_t *utils, | | | |
| sasl_mech_secret_t **psecret); | | | |
| | | | |
| /* perform precalculations during a network round-trip | | | |
| * or idle period. conn_context may be NULL | | | |
| * returns 1 if action taken, 0 if no action taken | | | |
| */ | | | |
| int (*idle)(void *glob_context, | | | |
| void *conn_context, | | | |
| sasl_client_params_t *cparams); | | | |
| } sasl_client_plug_t; | | } sasl_client_plug_t; | |
| | | | |
|
| #define SASL_CLIENT_PLUG_VERSION 3 | | #define SASL_CLIENT_PLUG_VERSION 4 | |
| | | | |
| /* plug-in entry point: | | /* plug-in entry point: | |
| * utils -- utility callback functions | | * utils -- utility callback functions | |
| * max_version -- highest client plug version supported | | * max_version -- highest client plug version supported | |
| * returns: | | * returns: | |
| * out_version -- client plug version of result | | * out_version -- client plug version of result | |
| * pluglist -- list of mechanism plug-ins | | * pluglist -- list of mechanism plug-ins | |
| * plugcount -- number of mechanism plug-ins | | * plugcount -- number of mechanism plug-ins | |
| * results: | | * results: | |
| * SASL_OK -- success | | * SASL_OK -- success | |
| * SASL_NOMEM -- failure | | * SASL_NOMEM -- failure | |
| * SASL_BADVERS -- max_version too small | | * SASL_BADVERS -- max_version too small | |
| * SASL_BADPARAM -- bad config string | | * SASL_BADPARAM -- bad config string | |
| * ... | | * ... | |
| */ | | */ | |
|
| typedef int sasl_client_plug_init_t(sasl_utils_t *utils, | | typedef int sasl_client_plug_init_t(const sasl_utils_t *utils, | |
| int max_version, | | int max_version, | |
| int *out_version, | | int *out_version, | |
|
| const sasl_client_plug_t **pluglist, | | sasl_client_plug_t **pluglist, | |
| int *plugcount); | | int *plugcount); | |
| | | | |
|
| | | /* add a client plug-in | |
| | | */ | |
| | | LIBSASL_API int sasl_client_add_plugin(const char *plugname, | |
| | | sasl_client_plug_init_t *cplugfunc); | |
| | | | |
| /******************** | | /******************** | |
| * Server Functions * | | * Server Functions * | |
| ********************/ | | ********************/ | |
| | | | |
|
| /* input parameters to server SASL plugin | | /* log message formatting routine */ | |
| | | typedef void sasl_logmsg_p(sasl_conn_t *conn, const char *fmt, ...); | |
| | | | |
| | | /* | |
| | | * input parameters to server SASL plugin | |
| | | * | |
| | | * created / destroyed by the glue code | |
| | | * | |
| */ | | */ | |
| typedef struct sasl_server_params { | | typedef struct sasl_server_params { | |
| const char *service; /* NULL = default service for user_exists | | const char *service; /* NULL = default service for user_exists | |
| and setpass */ | | and setpass */ | |
| const char *appname; /* name of calling application */ | | const char *appname; /* name of calling application */ | |
|
| const char *serverFQDN; /* local domain name */ | | const char *serverFQDN; /* server default fully qualified domain nam | |
| const char *user_realm; /* set of users who are active */ | | e | |
| sasl_utils_t *utils; /* SASL API utility routines */ | | * (e.g., gethostname) */ | |
| | | const char *user_realm; /* realm for user (NULL = client supplied) * | |
| | | / | |
| | | const char *iplocalport; /* server IP domain literal & port */ | |
| | | const char *ipremoteport; /* client IP domain literal & port */ | |
| | | | |
| | | unsigned servicelen; /* length of service */ | |
| | | unsigned applen; /* length of appname */ | |
| | | unsigned slen; /* length of serverFQDN */ | |
| | | unsigned urlen; /* length of user_realm */ | |
| | | unsigned iploclen; /* length of iplocalport */ | |
| | | unsigned ipremlen; /* length of ipremoteport */ | |
| | | | |
| | | /* This indicates the level of logging desired. See SASL_LOG_* | |
| | | * in sasl.h | |
| | | * | |
| | | * Plug-ins can ignore this and just pass their desired level to | |
| | | * the log callback. This is primarily used to eliminate logging which | |
| | | * might be a performance problem (e.g., full protocol trace) and | |
| | | * to select between SASL_LOG_TRACE and SASL_LOG_PASS alternatives | |
| | | */ | |
| | | int log_level; | |
| | | | |
| | | const sasl_utils_t *utils; /* SASL API utility routines -- | |
| | | * for a particular sasl_conn_t, | |
| | | * MUST remain valid until mech_free is | |
| | | * called */ | |
| | | const sasl_callback_t *callbacks; /* Callbacks from application */ | |
| | | | |
| /* application's security requirements */ | | /* application's security requirements */ | |
| sasl_security_properties_t props; | | sasl_security_properties_t props; | |
| sasl_ssf_t external_ssf; /* external SSF active */ | | sasl_ssf_t external_ssf; /* external SSF active */ | |
| | | | |
| /* server plug-in calls this when it first has access to the plaintext | | /* server plug-in calls this when it first has access to the plaintext | |
| * passphrase. This is used to transition users via setpass calls. | | * passphrase. This is used to transition users via setpass calls. | |
| * If passlen is 0, it defaults to strlen(pass). | | * If passlen is 0, it defaults to strlen(pass). | |
| * returns 0 if no entry added, 1 if entry added | | * returns 0 if no entry added, 1 if entry added | |
| */ | | */ | |
|
| int (*transition)(sasl_conn_t *conn, const char *pass, int passlen); | | int (*transition)(sasl_conn_t *conn, const char *pass, unsigned passlen | |
| const char *retain_users; /* users exempt from password REMOVE/DISABLE | | ); | |
| */ | | | |
| | | /* Canonicalize a user name from on-wire to internal format | |
| | | * added cjn 1999-09-21 | |
| | | * Must be called once user name aquired if canon_user is non-NULL. | |
| | | * conn connection context | |
| | | * user user name from wire protocol (need not be NUL terminate | |
| | | d) | |
| | | * ulen length of user name from wire protocol (0 = strlen(user | |
| | | )) | |
| | | * flags for SASL_CU_* flags | |
| | | * oparams the user, authid, ulen, alen, fields are | |
| | | * set appropriately after canonicalization/copying and | |
| | | * authorization of arguments | |
| | | * | |
| | | * responsible for setting user, ulen, authid, and alen in the oparams | |
| | | * structure | |
| | | * | |
| | | * default behavior is to strip leading and trailing whitespace, as | |
| | | * well as allocating space for and copying the parameters. | |
| | | * | |
| | | * results: | |
| | | * SASL_OK -- success | |
| | | * SASL_NOMEM -- out of memory | |
| | | * SASL_BADPARAM -- invalid conn | |
| | | * SASL_BADPROT -- invalid user/authid | |
| | | */ | |
| | | int (*canon_user)(sasl_conn_t *conn, | |
| | | const char *user, unsigned ulen, | |
| | | unsigned flags, | |
| | | sasl_out_params_t *oparams); | |
| | | | |
| | | /* auxiliary property context (see definitions in prop.h) | |
| | | * added cjn 2000-01-30 | |
| | | * | |
| | | * NOTE: these properties are the ones associated with the | |
| | | * canonicalized "user" (user to login as / authorization id), not | |
| | | * the "authid" (user whose credentials are used / authentication id) | |
| | | * Prefix the property name with a "*" if a property associated with | |
| | | * the "authid" is interesting. | |
| | | */ | |
| | | struct propctx *propctx; | |
| | | | |
| | | /* for additions which don't require a version upgrade; set to 0 */ | |
| | | void *spare_ptr1; | |
| | | void *spare_ptr2; | |
| | | void *spare_ptr3; | |
| | | void *spare_ptr4; | |
| | | int (*spare_fptr1)(); | |
| | | int (*spare_fptr2)(); | |
| | | int spare_int1; | |
| | | int spare_int2; | |
| | | int spare_int3; | |
| | | | |
| | | /* flags field as passed to sasl_server_new */ | |
| | | unsigned flags; | |
| | | | |
| /* set to 0 initially, this allows a plugin with extended parameters | | /* set to 0 initially, this allows a plugin with extended parameters | |
| * to work with an older framework by updating version as parameters | | * to work with an older framework by updating version as parameters | |
| * are added. | | * are added. | |
| */ | | */ | |
| int param_version; | | int param_version; | |
| } sasl_server_params_t; | | } sasl_server_params_t; | |
| | | | |
|
| | | /* logging levels (more levels may be added later, if necessary): | |
| | | */ | |
| | | #define SASL_LOG_NONE 0 /* don't log anything */ | |
| | | #define SASL_LOG_ERR 1 /* log unusual errors (default) */ | |
| | | #define SASL_LOG_FAIL 2 /* log all authentication failures */ | |
| | | #define SASL_LOG_WARN 3 /* log non-fatal warnings */ | |
| | | #define SASL_LOG_NOTE 4 /* more verbose than LOG_WARN */ | |
| | | #define SASL_LOG_DEBUG 5 /* more verbose than LOG_NOTE */ | |
| | | #define SASL_LOG_TRACE 6 /* traces of internal protocols */ | |
| | | #define SASL_LOG_PASS 7 /* traces of internal protocols, including | |
| | | * passwords */ | |
| | | | |
| /* additional flags for setpass() function below: | | /* additional flags for setpass() function below: | |
| */ | | */ | |
| /* SASL_SET_CREATE create user if pass non-NULL */ | | /* SASL_SET_CREATE create user if pass non-NULL */ | |
| /* SASL_SET_DISABLE disable user */ | | /* SASL_SET_DISABLE disable user */ | |
| #define SASL_SET_REMOVE SASL_SET_CREATE /* remove user if pass is NULL */ | | #define SASL_SET_REMOVE SASL_SET_CREATE /* remove user if pass is NULL */ | |
| | | | |
|
| | | /* features for server plug-in | |
| | | */ | |
| | | #define SASL_FEAT_SERVICE 0x0200 /* service-specific passwords supported | |
| | | */ | |
| | | #define SASL_FEAT_GETSECRET 0x0400 /* sasl_server_{get,put}secret_t callba | |
| | | cks | |
| | | * required by plug-in */ | |
| | | | |
| /* a C object for a server mechanism | | /* a C object for a server mechanism | |
| */ | | */ | |
| typedef struct sasl_server_plug { | | typedef struct sasl_server_plug { | |
| /* mechanism name */ | | /* mechanism name */ | |
| const char *mech_name; | | const char *mech_name; | |
| | | | |
| /* best mech additional security layer strength factor */ | | /* best mech additional security layer strength factor */ | |
| sasl_ssf_t max_ssf; | | sasl_ssf_t max_ssf; | |
| | | | |
| /* best security flags, as defined in sasl_security_properties_t */ | | /* best security flags, as defined in sasl_security_properties_t */ | |
|
| int security_flags; | | unsigned security_flags; | |
| | | | |
| | | /* features of plugin */ | |
| | | unsigned features; | |
| | | | |
| /* global state for mechanism */ | | /* global state for mechanism */ | |
| void *glob_context; | | void *glob_context; | |
| | | | |
| /* create a new mechanism handler | | /* create a new mechanism handler | |
| * glob_context -- global context | | * glob_context -- global context | |
| * sparams -- server config params | | * sparams -- server config params | |
| * challenge -- server challenge from previous instance or NULL | | * challenge -- server challenge from previous instance or NULL | |
| * challen -- length of challenge from previous instance or 0 | | * challen -- length of challenge from previous instance or 0 | |
| * out: | | * out: | |
| * conn_context -- connection context | | * conn_context -- connection context | |
|
| * errstr -- optional reply error string | | * errinfo -- error information | |
| * | | * | |
| * returns: | | * returns: | |
| * SASL_OK -- successfully created mech instance | | * SASL_OK -- successfully created mech instance | |
| * SASL_* -- any other server error code | | * SASL_* -- any other server error code | |
| */ | | */ | |
| int (*mech_new)(void *glob_context, | | int (*mech_new)(void *glob_context, | |
|
| sasl_server_params_t *sparams, | | sasl_server_params_t *sparams, | |
| const char *challenge, | | const char *challenge, | |
|
| int challen, | | unsigned challen, | |
| void **conn_context, | | void **conn_context); | |
| const char **errstr); | | | |
| | | | |
| /* perform one step in exchange | | /* perform one step in exchange | |
| * | | * | |
| * returns: | | * returns: | |
| * SASL_OK -- success, all done | | * SASL_OK -- success, all done | |
| * SASL_CONTINUE -- success, one more round trip | | * SASL_CONTINUE -- success, one more round trip | |
| * SASL_* -- any other server error code | | * SASL_* -- any other server error code | |
| */ | | */ | |
| int (*mech_step)(void *conn_context, | | int (*mech_step)(void *conn_context, | |
|
| sasl_server_params_t *sparams, | | sasl_server_params_t *sparams, | |
| const char *clientin, | | const char *clientin, | |
| int clientinlen, | | unsigned clientinlen, | |
| char **serverout, | | const char **serverout, | |
| int *serveroutlen, | | unsigned *serveroutlen, | |
| sasl_out_params_t *oparams, | | sasl_out_params_t *oparams); | |
| const char **errstr); | | | |
| | | | |
| /* dispose of a connection state | | /* dispose of a connection state | |
| */ | | */ | |
|
| void (*mech_dispose)(void *conn_context, sasl_utils_t *utils); | | void (*mech_dispose)(void *conn_context, const sasl_utils_t *utils); | |
| | | | |
| /* free global state for mechanism | | /* free global state for mechanism | |
| * mech_dispose must be called on all mechanisms first | | * mech_dispose must be called on all mechanisms first | |
| */ | | */ | |
|
| void (*mech_free)(void *glob_context, sasl_utils_t *utils); | | void (*mech_free)(void *glob_context, const sasl_utils_t *utils); | |
| | | | |
| /* set a password (optional) | | /* set a password (optional) | |
| * glob_context -- global context | | * glob_context -- global context | |
| * sparams -- service, middleware utilities, etc. props ignored | | * sparams -- service, middleware utilities, etc. props ignored | |
| * user -- user name | | * user -- user name | |
| * pass -- password/passphrase (NULL = disable/remove/delete) | | * pass -- password/passphrase (NULL = disable/remove/delete) | |
| * passlen -- length of password/passphrase | | * passlen -- length of password/passphrase | |
|
| | | * oldpass -- old password/passphrase (NULL = transition) | |
| | | * oldpasslen -- length of password/passphrase | |
| * flags -- see above | | * flags -- see above | |
|
| * errstr -- may be set to detailed error string | | | |
| * | | * | |
| * returns: | | * returns: | |
| * SASL_NOCHANGE -- no change was needed | | * SASL_NOCHANGE -- no change was needed | |
| * SASL_NOUSER -- no entry for user | | * SASL_NOUSER -- no entry for user | |
|
| * SASL_NOMECH -- no mechanism compatible entry for user | | * SASL_NOVERIFY -- no mechanism compatible entry for user | |
| * SASL_PWLOCK -- password locked | | * SASL_PWLOCK -- password locked | |
| * SASL_DIABLED -- account disabled | | * SASL_DIABLED -- account disabled | |
| * etc. | | * etc. | |
| */ | | */ | |
| int (*setpass)(void *glob_context, | | int (*setpass)(void *glob_context, | |
|
| sasl_server_params_t *sparams, | | sasl_server_params_t *sparams, | |
| const char *user, | | const char *user, | |
| const char *pass, | | const char *pass, unsigned passlen, | |
| unsigned passlen, | | const char *oldpass, unsigned oldpasslen, | |
| int flags, | | unsigned flags); | |
| const char **errstr); | | | |
| | | | |
|
| /* query which mechanisms are available to user | | /* query which mechanisms are available for user | |
| * glob_context -- context | | * glob_context -- context | |
| * sparams -- service, middleware utilities, etc. props ignored | | * sparams -- service, middleware utilities, etc. props ignored | |
| * user -- NUL terminated user name | | * user -- NUL terminated user name | |
| * maxmech -- max number of strings in mechlist (0 = no output) | | * maxmech -- max number of strings in mechlist (0 = no output) | |
| * output: | | * output: | |
| * mechlist -- an array of C string pointers, filled in with | | * mechlist -- an array of C string pointers, filled in with | |
| * mechanism names available to the user | | * mechanism names available to the user | |
| * | | * | |
| * returns: | | * returns: | |
| * SASL_OK -- success | | * SASL_OK -- success | |
| * SASL_NOMEM -- not enough memory | | * SASL_NOMEM -- not enough memory | |
| * SASL_FAIL -- lower level failure | | * SASL_FAIL -- lower level failure | |
| * SASL_DISABLED -- account disabled | | * SASL_DISABLED -- account disabled | |
| * SASL_NOUSER -- user not found | | * SASL_NOUSER -- user not found | |
| * SASL_BUFOVER -- maxmech is too small | | * SASL_BUFOVER -- maxmech is too small | |
|
| * SASL_NOMECH -- user found, but no mechanisms available | | * SASL_NOVERIFY -- user found, but no mechanisms available | |
| */ | | */ | |
| int (*user_query)(void *glob_context, | | int (*user_query)(void *glob_context, | |
| sasl_server_params_t *sparams, | | sasl_server_params_t *sparams, | |
| const char *user, | | const char *user, | |
| int maxmech, | | int maxmech, | |
| const char **mechlist); | | const char **mechlist); | |
| | | | |
|
| /* perform precalculations during a network round-trip | | /* perform precalculations during a network round-trip | |
| * or idle period. conn_context may be NULL (optional) | | * or idle period. conn_context may be NULL (optional) | |
| * returns 1 if action taken, 0 if no action taken | | * returns 1 if action taken, 0 if no action taken | |
| */ | | */ | |
| int (*idle)(void *glob_context, | | int (*idle)(void *glob_context, | |
| void *conn_context, | | void *conn_context, | |
| sasl_server_params_t *sparams); | | sasl_server_params_t *sparams); | |
| | | | |
| /* install credentials returned earlier by the plugin. */ | | /* check if mechanism is available | |
| int (*install_credentials)(void *conn_context, | | * optional--if NULL, mechanism is available based on ENABLE= in confi | |
| sasl_credentials_t *credentials); | | g | |
| /* uninstall credentials returned earlier by the plugin. */ | | * | |
| int (*uninstall_credentials)(void *conn_context, | | * If this routine sets conn_context to a non-NULL value, then the cal | |
| sasl_credentials_t *credentials); | | l | |
| /* free credentials returned earlier by the plugin. */ | | * to mech_new will be skipped. This should not be done unless | |
| int (*dispose_credentials)(void *conn_context, | | * there's a significant performance benefit, since it can cause | |
| sasl_credentials_t *credentials); | | * additional memory allocation in SASL core code to keep track of | |
| | | * contexts potentially for multiple mechanisms. | |
| | | * | |
| | | * This is called by the first call to sasl_listmech() for a | |
| | | * given connection context, thus for a given protocol it may | |
| | | * never be called. Note that if mech_avail returns SASL_NOMECH, | |
| | | * then that mechanism is considered disabled for the remainder | |
| | | * of the session. | |
| | | * | |
| | | * returns SASL_OK on success, | |
| | | * SASL_NOMECH if mech disabled | |
| | | */ | |
| | | int (*mech_avail)(void *glob_context, | |
| | | sasl_server_params_t *sparams, | |
| | | void **conn_context); | |
| | | | |
| | | /* for additions which don't require a version upgrade; set to 0 */ | |
| | | int (*spare_fptr2)(); | |
| } sasl_server_plug_t; | | } sasl_server_plug_t; | |
| | | | |
|
| #define SASL_SERVER_PLUG_VERSION 3 | | #define SASL_SERVER_PLUG_VERSION 4 | |
| | | | |
| /* plug-in entry point: | | /* plug-in entry point: | |
| * utils -- utility callback functions | | * utils -- utility callback functions | |
|
| | | * plugname -- name of plug-in (may be NULL) | |
| * max_version -- highest server plug version supported | | * max_version -- highest server plug version supported | |
| * returns: | | * returns: | |
| * out_version -- server plug-in version of result | | * out_version -- server plug-in version of result | |
| * pluglist -- list of mechanism plug-ins | | * pluglist -- list of mechanism plug-ins | |
| * plugcount -- number of mechanism plug-ins | | * plugcount -- number of mechanism plug-ins | |
| * results: | | * results: | |
| * SASL_OK -- success | | * SASL_OK -- success | |
| * SASL_NOMEM -- failure | | * SASL_NOMEM -- failure | |
| * SASL_BADVERS -- max_version too small | | * SASL_BADVERS -- max_version too small | |
| * SASL_BADPARAM -- bad config string | | * SASL_BADPARAM -- bad config string | |
| * ... | | * ... | |
| */ | | */ | |
|
| typedef int sasl_server_plug_init_t(sasl_utils_t *utils, | | typedef int sasl_server_plug_init_t(const sasl_utils_t *utils, | |
| int max_version, | | int max_version, | |
| int *out_version, | | int *out_version, | |
|
| const sasl_server_plug_t **pluglist, | | sasl_server_plug_t **pluglist, | |
| int *plugcount); | | int *plugcount); | |
| | | | |
|
| | | /* | |
| | | * add a server plug-in | |
| | | */ | |
| | | LIBSASL_API int sasl_server_add_plugin(const char *plugname, | |
| | | sasl_server_plug_init_t *splugfunc); | |
| | | | |
| | | /********************************************************* | |
| | | * user canonicalization plug-in -- added cjn 1999-09-29 * | |
| | | *********************************************************/ | |
| | | | |
| | | typedef struct sasl_canonuser { | |
| | | /* optional features of plugin (set to 0) */ | |
| | | int features; | |
| | | | |
| | | /* spare integer (set to 0) */ | |
| | | int spare_int1; | |
| | | | |
| | | /* global state for plugin */ | |
| | | void *glob_context; | |
| | | | |
| | | /* name of plugin */ | |
| | | void *spare_ptr1; | |
| | | | |
| | | /* free global state for plugin */ | |
| | | void (*canon_user_free)(void *glob_context, const sasl_utils_t *utils); | |
| | | | |
| | | /* canonicalize a username | |
| | | * glob_context -- global context from this structure | |
| | | * sparams -- server params, note user_realm&propctx elements | |
| | | * user -- user to login as (may not be NUL terminated) | |
| | | * len -- length of user name (0 = strlen(user)) | |
| | | * flags -- for SASL_CU_* flags | |
| | | * out -- buffer to copy user name | |
| | | * out_max -- max length of user name | |
| | | * out_len -- set to length of user name | |
| | | * | |
| | | * note that the output buffers MAY be the same as the input buffers. | |
| | | * | |
| | | * returns | |
| | | * SASL_OK on success | |
| | | * SASL_BADPROT username contains invalid character | |
| | | */ | |
| | | int (*canon_user_server)(void *glob_context, | |
| | | sasl_server_params_t *sparams, | |
| | | const char *user, unsigned len, | |
| | | unsigned flags, | |
| | | char *out, | |
| | | unsigned out_umax, unsigned *out_ulen); | |
| | | | |
| | | int (*canon_user_client)(void *glob_context, | |
| | | sasl_client_params_t *cparams, | |
| | | const char *user, unsigned len, | |
| | | unsigned flags, | |
| | | char *out, | |
| | | unsigned out_max, unsigned *out_len); | |
| | | | |
| | | /* for additions which don't require a version upgrade; set to 0 */ | |
| | | int (*spare_fptr1)(); | |
| | | int (*spare_fptr2)(); | |
| | | int (*spare_fptr3)(); | |
| | | } sasl_canonuser_plug_t; | |
| | | | |
| | | #define SASL_CANONUSER_PLUG_VERSION 5 | |
| | | | |
| | | /* default name for canonuser plug-in entry point is "sasl_canonuser_init" | |
| | | * similar to sasl_server_plug_init model, except only returns one | |
| | | * sasl_canonuser_plug_t structure; | |
| | | */ | |
| | | typedef int sasl_canonuser_init_t(const sasl_utils_t *utils, | |
| | | int max_version, | |
| | | int *out_version, | |
| | | sasl_canonuser_plug_t **plug, | |
| | | const char *plugname); | |
| | | | |
| | | /* add a canonuser plugin | |
| | | */ | |
| | | LIBSASL_API int sasl_canonuser_add_plugin(const char *plugname, | |
| | | sasl_canonuser_init_t *canonuserfunc); | |
| | | | |
| | | /****************************************************** | |
| | | * auxiliary property plug-in -- added cjn 1999-09-29 * | |
| | | ******************************************************/ | |
| | | | |
| | | typedef struct sasl_auxprop_plug { | |
| | | /* optional features of plugin (none defined yet, set to 0) */ | |
| | | int features; | |
| | | | |
| | | /* spare integer, must be set to 0 */ | |
| | | int spare_int1; | |
| | | | |
| | | /* global state for plugin */ | |
| | | void *glob_context; | |
| | | | |
| | | /* free global state for plugin (OPTIONAL) */ | |
| | | void (*auxprop_free)(void *glob_context, const sasl_utils_t *utils); | |
| | | | |
| | | /* fill in fields of an auxiliary property context | |
| | | * last element in array has id of SASL_AUX_END | |
| | | * elements with non-0 len should be ignored. | |
| | | */ | |
| | | void (*auxprop_lookup)(void *glob_context, | |
| | | sasl_server_params_t *sparams, | |
| | | unsigned flags, | |
| | | const char *user, unsigned ulen); | |
| | | | |
| | | /* for additions which don't require a version upgrade; set to 0 */ | |
| | | void (*spare_fptr1)(); | |
| | | void (*spare_fptr2)(); | |
| | | } sasl_auxprop_plug_t; | |
| | | | |
| | | /* auxprop lookup flags */ | |
| | | #define SASL_AUXPROP_OVERRIDE 0x01 /* if clear, ignore auxiliary properties | |
| | | * with non-zero len field. If set, | |
| | | * override value of those properties */ | |
| | | | |
| | | #define SASL_AUXPROP_PLUG_VERSION 4 | |
| | | | |
| | | /* default name for auxprop plug-in entry point is "sasl_auxprop_init" | |
| | | * similar to sasl_server_plug_init model, except only returns one | |
| | | * sasl_auxprop_plug_t structure; | |
| | | */ | |
| | | typedef int sasl_auxprop_init_t(const sasl_utils_t *utils, | |
| | | int max_version, | |
| | | int *out_version, | |
| | | sasl_auxprop_plug_t **plug, | |
| | | const char *plugname); | |
| | | | |
| | | /* add an auxiliary property plug-in | |
| | | */ | |
| | | LIBSASL_API int sasl_auxprop_add_plugin(const char *plugname, | |
| | | sasl_auxprop_init_t *auxpropfunc); | |
| | | | |
| #endif /* SASLPLUG_H */ | | #endif /* SASLPLUG_H */ | |
| | | | |
End of changes. 60 change blocks. |
| 212 lines changed or deleted | | 553 lines changed or added | |
|