diff options
author | molotkov-and <molotkov-and@ydb.tech> | 2023-08-18 17:20:47 +0300 |
---|---|---|
committer | molotkov-and <molotkov-and@ydb.tech> | 2023-08-18 19:42:07 +0300 |
commit | 73215359bc33e76f5b94d1832a377072bf245cfc (patch) | |
tree | 9cb8ad61d8c3cd107353d42951560ff3cf1b966d /contrib/libs/sasl/include | |
parent | 1cbfd34a55732f7b1d407986b45e40853f01f2c2 (diff) | |
download | ydb-73215359bc33e76f5b94d1832a377072bf245cfc.tar.gz |
KIKIMR-18220: Enrich token with groups from LDAP
Add ldap functions wrapper and separate in different files for compatibility with different OS.
Add user groups fetching from ldap server.
Limitations:
- Fixed 'memberOf' attribute
- No tests to check how filter for search created
- Fetched groups are returned in event as is.
Diffstat (limited to 'contrib/libs/sasl/include')
-rw-r--r-- | contrib/libs/sasl/include/exits.h | 118 | ||||
-rw-r--r-- | contrib/libs/sasl/include/gai.h | 108 | ||||
-rw-r--r-- | contrib/libs/sasl/include/hmac-md5.h | 59 | ||||
-rw-r--r-- | contrib/libs/sasl/include/md5.h | 42 | ||||
-rw-r--r-- | contrib/libs/sasl/include/md5global.h | 38 | ||||
-rw-r--r-- | contrib/libs/sasl/include/prop.h | 170 | ||||
-rw-r--r-- | contrib/libs/sasl/include/sasl.h | 1332 | ||||
-rw-r--r-- | contrib/libs/sasl/include/sasl/prop.h | 170 | ||||
-rw-r--r-- | contrib/libs/sasl/include/sasl/sasl.h | 1332 | ||||
-rw-r--r-- | contrib/libs/sasl/include/saslplug.h | 986 | ||||
-rw-r--r-- | contrib/libs/sasl/include/saslutil.h | 99 |
11 files changed, 4454 insertions, 0 deletions
diff --git a/contrib/libs/sasl/include/exits.h b/contrib/libs/sasl/include/exits.h new file mode 100644 index 0000000000..464cb11bab --- /dev/null +++ b/contrib/libs/sasl/include/exits.h @@ -0,0 +1,118 @@ +/* + * Copyright (c) 1987, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)sysexits.h 8.1 (Berkeley) 6/2/93 + */ + +#ifndef _SYSEXITS_H_ +#define _SYSEXITS_H_ + +/* + * SYSEXITS.H -- Exit status codes for system programs. + * + * This include file attempts to categorize possible error + * exit statuses for system programs, notably delivermail + * and the Berkeley network. + * + * Error numbers begin at EX__BASE to reduce the possibility of + * clashing with other exit statuses that random programs may + * already return. The meaning of the codes is approximately + * as follows: + * + * EX_USAGE -- The command was used incorrectly, e.g., with + * the wrong number of arguments, a bad flag, a bad + * syntax in a parameter, or whatever. + * EX_DATAERR -- The input data was incorrect in some way. + * This should only be used for user's data & not + * system files. + * EX_NOINPUT -- An input file (not a system file) did not + * exist or was not readable. This could also include + * errors like "No message" to a mailer (if it cared + * to catch it). + * EX_NOUSER -- The user specified did not exist. This might + * be used for mail addresses or remote logins. + * EX_NOHOST -- The host specified did not exist. This is used + * in mail addresses or network requests. + * EX_UNAVAILABLE -- A service is unavailable. This can occur + * if a support program or file does not exist. This + * can also be used as a catchall message when something + * you wanted to do doesn't work, but you don't know + * why. + * EX_SOFTWARE -- An internal software error has been detected. + * This should be limited to non-operating system related + * errors as possible. + * EX_OSERR -- An operating system error has been detected. + * This is intended to be used for such things as "cannot + * fork", "cannot create pipe", or the like. It includes + * things like getuid returning a user that does not + * exist in the passwd file. + * EX_OSFILE -- Some system file (e.g., /etc/passwd, /etc/utmp, + * etc.) does not exist, cannot be opened, or has some + * sort of error (e.g., syntax error). + * EX_CANTCREAT -- A (user specified) output file cannot be + * created. + * EX_IOERR -- An error occurred while doing I/O on some file. + * EX_TEMPFAIL -- temporary failure, indicating something that + * is not really an error. In sendmail, this means + * that a mailer (e.g.) could not create a connection, + * and the request should be reattempted later. + * EX_PROTOCOL -- the remote system returned something that + * was "not possible" during a protocol exchange. + * EX_NOPERM -- You did not have sufficient permission to + * perform the operation. This is not intended for + * file system problems, which should use NOINPUT or + * CANTCREAT, but rather for higher level permissions. + */ + +#define EX_OK 0 /* successful termination */ + +#define EX__BASE 64 /* base value for error messages */ + +#define EX_USAGE 64 /* command line usage error */ +#define EX_DATAERR 65 /* data format error */ +#define EX_NOINPUT 66 /* cannot open input */ +#define EX_NOUSER 67 /* addressee unknown */ +#define EX_NOHOST 68 /* host name unknown */ +#define EX_UNAVAILABLE 69 /* service unavailable */ +#define EX_SOFTWARE 70 /* internal software error */ +#define EX_OSERR 71 /* system error (e.g., can't fork) */ +#define EX_OSFILE 72 /* critical OS file missing */ +#define EX_CANTCREAT 73 /* can't create (user) output file */ +#define EX_IOERR 74 /* input/output error */ +#define EX_TEMPFAIL 75 /* temp failure; user is invited to retry */ +#define EX_PROTOCOL 76 /* remote error in protocol */ +#define EX_NOPERM 77 /* permission denied */ +#define EX_CONFIG 78 /* configuration error */ + +#define EX__MAX 78 /* maximum listed value */ + +#endif /* !_SYSEXITS_H_ */ diff --git a/contrib/libs/sasl/include/gai.h b/contrib/libs/sasl/include/gai.h new file mode 100644 index 0000000000..59a38988ea --- /dev/null +++ b/contrib/libs/sasl/include/gai.h @@ -0,0 +1,108 @@ +/* + * Mar 8, 2000 by Hajimu UMEMOTO <ume@mahoroba.org> + * + * This module is besed on ssh-1.2.27-IPv6-1.5 written by + * KIKUCHI Takahiro <kick@kyoto.wide.ad.jp> + */ +/* + * Copyright (c) 1998-2016 Carnegie Mellon University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any other legal + * details, please contact + * Carnegie Mellon University + * Center for Technology Transfer and Enterprise Creation + * 4615 Forbes Avenue + * Suite 302 + * Pittsburgh, PA 15213 + * (412) 268-7393, fax: (412) 268-7395 + * innovation@andrew.cmu.edu + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +/* + * fake library for ssh + * + * This file is included in getaddrinfo.c and getnameinfo.c. + * See getaddrinfo.c and getnameinfo.c. + */ + +#ifndef _GAI_H_ +#define _GAI_H_ + +#ifndef NI_MAXHOST +#define NI_MAXHOST 1025 +#endif +#ifndef NI_MAXSERV +#define NI_MAXSERV 32 +#endif + +/* for old netdb.h */ +#ifndef EAI_NODATA +#define EAI_NODATA 1 +#define EAI_MEMORY 2 +#define EAI_FAMILY 5 /* ai_family not supported */ +#define EAI_SERVICE 9 /* servname not supported for ai_socktype */ +#endif + +/* dummy value for old netdb.h */ +#ifndef AI_PASSIVE +#define AI_PASSIVE 1 +#define AI_CANONNAME 2 +struct addrinfo { + int ai_flags; /* AI_PASSIVE, AI_CANONNAME */ + int ai_family; /* PF_xxx */ + int ai_socktype; /* SOCK_xxx */ + int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */ + size_t ai_addrlen; /* length of ai_addr */ + char *ai_canonname; /* canonical name for hostname */ + struct sockaddr *ai_addr; /* binary address */ + struct addrinfo *ai_next; /* next structure in linked list */ +}; +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef HAVE_GETNAMEINFO +int getnameinfo(const struct sockaddr *, socklen_t, char *, + size_t, char *, size_t, int); +#endif + +#ifndef HAVE_GETADDRINFO +int getaddrinfo(const char *, const char *, + const struct addrinfo *, struct addrinfo **); +void freeaddrinfo(struct addrinfo *); +char *gai_strerror(int); +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/contrib/libs/sasl/include/hmac-md5.h b/contrib/libs/sasl/include/hmac-md5.h new file mode 100644 index 0000000000..ff81a9d871 --- /dev/null +++ b/contrib/libs/sasl/include/hmac-md5.h @@ -0,0 +1,59 @@ +/* hmac-md5.h -- HMAC_MD5 functions + */ + +#ifndef HMAC_MD5_H +#define HMAC_MD5_H 1 + +#define HMAC_MD5_SIZE 16 + +/* intermediate MD5 context */ +typedef struct HMAC_MD5_CTX_s { + MD5_CTX ictx, octx; +} HMAC_MD5_CTX; + +/* intermediate HMAC state + * values stored in network byte order (Big Endian) + */ +typedef struct HMAC_MD5_STATE_s { + SASL_UINT4 istate[4]; + SASL_UINT4 ostate[4]; +} HMAC_MD5_STATE; + +#ifdef __cplusplus +extern "C" { +#endif + +/* One step hmac computation + * + * digest may be same as text or key + */ +void _sasl_hmac_md5(const unsigned char *text, int text_len, + const unsigned char *key, int key_len, + unsigned char digest[HMAC_MD5_SIZE]); + +/* create context from key + */ +void _sasl_hmac_md5_init(HMAC_MD5_CTX *hmac, + const unsigned char *key, int key_len); + +/* precalculate intermediate state from key + */ +void _sasl_hmac_md5_precalc(HMAC_MD5_STATE *hmac, + const unsigned char *key, int key_len); + +/* initialize context from intermediate state + */ +void _sasl_hmac_md5_import(HMAC_MD5_CTX *hmac, HMAC_MD5_STATE *state); + +#define _sasl_hmac_md5_update(hmac, text, text_len) _sasl_MD5Update(&(hmac)->ictx, (text), (text_len)) + +/* finish hmac from intermediate result. Intermediate result is zeroed. + */ +void _sasl_hmac_md5_final(unsigned char digest[HMAC_MD5_SIZE], + HMAC_MD5_CTX *hmac); + +#ifdef __cplusplus +} +#endif + +#endif /* HMAC_MD5_H */ diff --git a/contrib/libs/sasl/include/md5.h b/contrib/libs/sasl/include/md5.h new file mode 100644 index 0000000000..3571930158 --- /dev/null +++ b/contrib/libs/sasl/include/md5.h @@ -0,0 +1,42 @@ +/* MD5.H - header file for MD5C.C + */ + +/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All +rights reserved. + +License to copy and use this software is granted provided that it +is identified as the "RSA Data Security, Inc. MD5 Message-Digest +Algorithm" in all material mentioning or referencing this software +or this function. + +License is also granted to make and use derivative works provided +that such works are identified as "derived from the RSA Data +Security, Inc. MD5 Message-Digest Algorithm" in all material +mentioning or referencing the derived work. + +RSA Data Security, Inc. makes no representations concerning either +the merchantability of this software or the suitability of this +software for any particular purpose. It is provided "as is" +without express or implied warranty of any kind. +These notices must be retained in any copies of any part of this +documentation and/or software. + */ + +/* MD5 context. */ +typedef struct { + SASL_UINT4 state[4]; /* state (ABCD) */ + SASL_UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */ + unsigned char buffer[64]; /* input buffer */ +} MD5_CTX; + +#ifdef __cplusplus +extern "C" { +#endif + +void _sasl_MD5Init (MD5_CTX *); +void _sasl_MD5Update (MD5_CTX *, const unsigned char *, unsigned int); +void _sasl_MD5Final (unsigned char [16], MD5_CTX *); + +#ifdef __cplusplus +} +#endif diff --git a/contrib/libs/sasl/include/md5global.h b/contrib/libs/sasl/include/md5global.h new file mode 100644 index 0000000000..034d9fa2d4 --- /dev/null +++ b/contrib/libs/sasl/include/md5global.h @@ -0,0 +1,38 @@ +/* GLOBAL.H - RSAREF types and constants + */ +#ifndef MD5GLOBAL_H +#define MD5GLOBAL_H + +/* PROTOTYPES should be set to one if and only if the compiler supports + function argument prototyping. +The following makes PROTOTYPES default to 0 if it has not already + been defined with C compiler flags. + */ +#ifndef PROTOTYPES +#define PROTOTYPES 0 +#endif + +/* POINTER defines a generic pointer type */ +typedef unsigned char *POINTER; + +typedef signed char SASL_INT1; /* 8 bits */ +typedef short SASL_INT2; /* 16 bits */ +typedef int SASL_INT4; /* 32 bits */ +typedef long SASL_INT8; /* 64 bits */ +typedef unsigned char SASL_UINT1; /* 8 bits */ +typedef unsigned short SASL_UINT2; /* 16 bits */ +typedef unsigned int SASL_UINT4; /* 32 bits */ +typedef unsigned long SASL_UINT8; /* 64 bits */ + +/* PROTO_LIST is defined depending on how PROTOTYPES is defined above. +If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it +returns an empty list. +*/ +#if PROTOTYPES +#define PROTO_LIST(list) list +#else +#define PROTO_LIST(list) () +#endif + +#endif /* MD5GLOBAL_H */ + diff --git a/contrib/libs/sasl/include/prop.h b/contrib/libs/sasl/include/prop.h new file mode 100644 index 0000000000..bf091d67d8 --- /dev/null +++ b/contrib/libs/sasl/include/prop.h @@ -0,0 +1,170 @@ +/* prop.h -- property request/response management routines + * + * Author: Chris Newman + * Removal of implementation-specific details by: Rob Siemborski + * + * This is intended to be used to create a list of properties to request, + * and _then_ request values for all properties. Any change to the request + * list will discard any existing values. This assumption allows a very + * efficient and simple memory model. This was designed for SASL API auxiliary + * property support, but would be fine for other contexts where this property + * model is appropriate. + * + * The "struct propctx" is allocated by prop_new and is a fixed size structure. + * If a prop_init() call were added, it would be reasonable to embed a "struct + * propctx" in another structure. prop_new also allocates a pool of memory + * (in the vbase field) which will be used for an array of "struct propval" + * to list all the requested properties. + * + * Properties may be multi-valued. + */ + +#ifndef PROP_H +#define PROP_H 1 + +/* The following ifdef block is the standard way of creating macros + * which make exporting from a DLL simpler. All files within this DLL + * 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.) */ +# define LIBSASL_API extern + +/* Same as above, but used during a variable declaration. */ +# define LIBSASL_VAR extern + +/* the resulting structure for property values + */ +struct propval { + const char *name; /* name of property; NULL = end of list */ + /* same pointer used in request will be used here */ + const char **values; /* list of strings, values == NULL if property not + * found, *values == NULL if property found with + * no values */ + unsigned nvalues; /* total number of value strings */ + unsigned valsize; /* total size in characters of all value strings */ +}; + +/* + * private internal structure + */ +#define PROP_DEFAULT 4 /* default number of propvals to assume */ +struct propctx; + +#ifdef __cplusplus +extern "C" { +#endif + +/* create a property context + * estimate -- an estimate of the storage needed for requests & responses + * 0 will use module default + * returns a new property context on success and NULL on any error + */ +LIBSASL_API struct propctx *prop_new(unsigned estimate); + +/* create new propctx which duplicates the contents of an existing propctx + * returns SASL_OK on success + * possible other return values include: SASL_NOMEM, SASL_BADPARAM + */ +LIBSASL_API int prop_dup(struct propctx *src_ctx, struct propctx **dst_ctx); + +/* Add property names to request + * ctx -- context from prop_new() + * names -- list of property names; must persist until context freed + * or requests cleared (This extends to other contexts that + * are dup'ed from this one, and their children, etc) + * + * NOTE: may clear values from context as side-effect + * returns SASL_OK on success + * possible other return values include: SASL_NOMEM, SASL_BADPARAM + */ +LIBSASL_API int prop_request(struct propctx *ctx, const char **names); + +/* return array of struct propval from the context + * return value persists until next call to + * prop_request, prop_clear or prop_dispose on context + * + * returns NULL on error + */ +LIBSASL_API const struct propval *prop_get(struct propctx *ctx); + +/* Fill in an array of struct propval based on a list of property names + * return value persists until next call to + * prop_request, prop_clear or prop_dispose on context + * returns number of matching properties which were found (values != NULL) + * if a name requested here was never requested by a prop_request, then + * the name field of the associated vals entry will be set to NULL + * + * The vals array MUST be atleast as long as the names array. + * + * returns # of matching properties on success + * possible other return values include: SASL_BADPARAM + */ +LIBSASL_API int prop_getnames(struct propctx *ctx, const char **names, + struct propval *vals); + +/* clear values and optionally requests from property context + * ctx -- property context + * requests -- 0 = don't clear requests, 1 = clear requests + */ +LIBSASL_API void prop_clear(struct propctx *ctx, int requests); + +/* erase the value of a property + */ +LIBSASL_API void prop_erase(struct propctx *ctx, const char *name); + +/* dispose of property context + * ctx -- is disposed and set to NULL; noop if ctx or *ctx is NULL + */ +LIBSASL_API void prop_dispose(struct propctx **ctx); + + +/****fetcher interfaces****/ + +/* format the requested property names into a string + * ctx -- context from prop_new()/prop_request() + * sep -- separator between property names (unused if none requested) + * seplen -- length of separator, if < 0 then strlen(sep) will be used + * outbuf -- output buffer + * outmax -- maximum length of output buffer including NUL terminator + * outlen -- set to length of output string excluding NUL terminator + * returns SASL_OK on success + * returns SASL_BADPARAM or amount of additional space needed on failure + */ +LIBSASL_API int prop_format(struct propctx *ctx, const char *sep, int seplen, + char *outbuf, unsigned outmax, unsigned *outlen); + +/* add a property value to the context + * ctx -- context from prop_new()/prop_request() + * name -- name of property to which value will be added + * if NULL, add to the same name as previous prop_set/setvals call + * value -- a value for the property; will be copied into context + * if NULL, remove existing values + * vallen -- length of value, if <= 0 then strlen(value) will be used + * returns SASL_OK on success + * possible error return values include: SASL_BADPARAM, SASL_NOMEM + */ +LIBSASL_API int prop_set(struct propctx *ctx, const char *name, + const char *value, int vallen); + +/* set the values for a property + * ctx -- context from prop_new()/prop_request() + * name -- name of property to which value will be added + * if NULL, add to the same name as previous prop_set/setvals call + * values -- array of values, ending in NULL. Each value is a NUL terminated + * string + * returns SASL_OK on success + * possible error return values include: SASL_BADPARAM, SASL_NOMEM + */ +LIBSASL_API int prop_setvals(struct propctx *ctx, const char *name, + const char **values); + +#ifdef __cplusplus +} +#endif + +#endif /* PROP_H */ diff --git a/contrib/libs/sasl/include/sasl.h b/contrib/libs/sasl/include/sasl.h new file mode 100644 index 0000000000..dc04ca4714 --- /dev/null +++ b/contrib/libs/sasl/include/sasl.h @@ -0,0 +1,1332 @@ +/* This is a proposed C API for support of SASL + * + *********************************IMPORTANT******************************* + * send email to chris.newman@innosoft.com and cyrus-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: + * sasl_conn_t Context for a SASL connection negotiation + * sasl_ssf_t Security layer Strength Factor + * sasl_callback_t A typed client/server callback function and context + * sasl_interact_t A client interaction descriptor + * sasl_secret_t A client password + * sasl_rand_t Random data context structure + * sasl_security_properties_t An application's required security level + * + * Callbacks: + * sasl_getopt_t client/server: Get an option value + * sasl_logmsg_t client/server: Log message handler + * sasl_getsimple_t client: Get user/language list + * sasl_getsecret_t client: Get authentication secret + * sasl_chalprompt_t client: Display challenge and prompt for response + * + * Server only Callbacks: + * sasl_authorize_t user authorization policy callback + * sasl_getconfpath_t get path to search for config file + * 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: + * sasl_done Release all SASL global state + * sasl_dispose Connection done: Dispose of sasl_conn_t + * sasl_getprop Get property (e.g., user name, security layer info) + * sasl_setprop Set property (e.g., external ssf) + * sasl_errdetail Generate string from last error on connection + * sasl_errstring Translate sasl error code to a string + * sasl_encode Encode data to send using security layer + * sasl_decode Decode data received using security layer + * + * Utility functions: + * sasl_encode64 Encode data to send using MIME base64 encoding + * sasl_decode64 Decode data received using MIME base64 encoding + * sasl_erasebuffer Erase a buffer + * + * Client Function Summary: + * sasl_client_init Load and initialize client plug-ins (call once) + * sasl_client_new Initialize client connection context: sasl_conn_t + * sasl_client_start Select mechanism for connection + * sasl_client_step Perform one authentication step + * + * Server Function Summary + * sasl_server_init Load and initialize server plug-ins (call once) + * sasl_server_new Initialize server connection context: sasl_conn_t + * sasl_listmech Create list of available mechanisms + * sasl_server_start Begin an authentication exchange + * sasl_server_step Perform one authentication exchange step + * sasl_checkpass Check a plaintext passphrase + * 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_auxprop_request Request auxiliary properties + * sasl_auxprop_getctx Get auxiliary property context for connection + * sasl_auxprop_store Store a set of auxiliary properties + * + * Basic client model: + * 1. client calls sasl_client_init() at startup to load plug-ins + * 2. when connection formed, call sasl_client_new() + * 3. once list of supported mechanisms received from server, client + * calls sasl_client_start(). goto 4a + * 4. client calls sasl_client_step() + * [4a. If SASL_INTERACT, fill in prompts and goto 4 + * -- doesn't happen if callbacks provided] + * 4b. If SASL error, goto 7 or 3 + * 4c. If SASL_OK, continue or goto 6 if last server response was success + * 5. send message to server, wait for response + * 5a. On data or success with server response, goto 4 + * 5b. On failure goto 7 or 3 + * 5c. On success with no server response continue + * 6. continue with application protocol until connection closes + * call sasl_getprop/sasl_encode/sasl_decode() if using security layer + * 7. call sasl_dispose(), may return to step 2 + * 8. call sasl_done() when program terminates + * + * Basic Server model: + * 1. call sasl_server_init() at startup to load plug-ins + * 2. On connection, call sasl_server_new() + * 3. call sasl_listmech() and send list to client] + * 4. after client AUTH command, call sasl_server_start(), goto 5a + * 5. call sasl_server_step() + * 5a. If SASL_CONTINUE, output to client, wait response, repeat 5 + * 5b. If SASL error, then goto 7 + * 5c. If SASL_OK, move on + * 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 + * 7. call sasl_dispose(), may return to step 2 + * 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 +#define SASL_H 1 + +#include <stddef.h> /* For size_t */ + +/* Keep in sync with win32/common.mak */ +#define SASL_VERSION_MAJOR 2 +#define SASL_VERSION_MINOR 1 +#define SASL_VERSION_STEP 28 + +/* A convenience macro: same as was defined in the OpenLDAP LDAPDB */ +#define SASL_VERSION_FULL ((SASL_VERSION_MAJOR << 16) |\ + (SASL_VERSION_MINOR << 8) | SASL_VERSION_STEP) + +#include "prop.h" + +/************* + * Basic API * + *************/ + +/* SASL result codes: */ +#define SASL_CONTINUE 1 /* another step is needed in authentication */ +#define SASL_OK 0 /* successful result */ +#define SASL_FAIL -1 /* generic failure */ +#define SASL_NOMEM -2 /* memory shortage failure */ +#define SASL_BUFOVER -3 /* overflowed buffer */ +#define SASL_NOMECH -4 /* mechanism not supported */ +#define SASL_BADPROT -5 /* bad protocol / cancel */ +#define SASL_NOTDONE -6 /* can't request info until later in exchange */ +#define SASL_BADPARAM -7 /* invalid parameter supplied */ +#define SASL_TRYAGAIN -8 /* transient failure (e.g., weak key) */ +#define SASL_BADMAC -9 /* integrity check failed */ +#define SASL_NOTINIT -12 /* SASL library not initialized */ + /* -- client only codes -- */ +#define SASL_INTERACT 2 /* needs user interaction */ +#define SASL_BADSERV -10 /* server failed mutual authentication step */ +#define SASL_WRONGMECH -11 /* mechanism doesn't support requested feature */ + /* -- server only codes -- */ +#define SASL_BADAUTH -13 /* authentication failure */ +#define SASL_NOAUTHZ -14 /* authorization failure */ +#define SASL_TOOWEAK -15 /* mechanism too weak for this user */ +#define SASL_ENCRYPT -16 /* encryption needed to use mechanism */ +#define SASL_TRANS -17 /* One time use of a plaintext password will + enable requested mechanism for user */ +#define SASL_EXPIRED -18 /* passphrase expired, has to be reset */ +#define SASL_DISABLED -19 /* account disabled */ +#define SASL_NOUSER -20 /* user not found */ +#define SASL_BADVERS -23 /* version mismatch with plug-in */ +#define SASL_UNAVAIL -24 /* remote authentication server unavailable */ +#define SASL_NOVERIFY -26 /* user exists, but no verifier for user */ + /* -- codes for password setting -- */ +#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 */ +#define SASL_NEED_OLD_PASSWD -29 /* sasl_setpass needs old password in order + to perform password change */ +#define SASL_CONSTRAINT_VIOLAT -30 /* a property can't be stored, + because of some constrains/policy violation */ + +#define SASL_BADBINDING -32 /* channel binding failure */ +#define SASL_CONFIGERR -100 /* error when parsing configuration file */ + +/* max size of a sasl mechanism name */ +#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 + */ +typedef struct sasl_conn sasl_conn_t; + +/* Plain text password structure. + * len is the length of the password, data is the text. + */ +typedef struct sasl_secret { + unsigned long len; + unsigned char data[1]; /* variable sized */ +} sasl_secret_t; + +/* random data context structure + */ +typedef struct sasl_rand_s sasl_rand_t; + +#ifdef __cplusplus +extern "C" { +#endif + +/**************************** + * Configure Basic Services * + ****************************/ + +/* the following functions are used to adjust how allocation and mutexes work + * they must be called before all other SASL functions: + */ + +#include <sys/types.h> + +/* memory allocation functions which may optionally be replaced: + */ +typedef void *sasl_malloc_t(size_t); +typedef void *sasl_calloc_t(size_t, size_t); +typedef void *sasl_realloc_t(void *, size_t); +typedef void sasl_free_t(void *); + +LIBSASL_API void sasl_set_alloc(sasl_malloc_t *, + sasl_calloc_t *, + sasl_realloc_t *, + sasl_free_t *); + +/* mutex functions which may optionally be replaced: + * sasl_mutex_alloc allocates a mutex structure + * sasl_mutex_lock blocks until mutex locked + * returns -1 on deadlock or parameter error + * returns 0 on success + * sasl_mutex_unlock unlocks mutex if it's locked + * returns -1 if not locked or parameter error + * returns 0 on success + * sasl_mutex_free frees a mutex structure + */ +typedef void *sasl_mutex_alloc_t(void); +typedef int sasl_mutex_lock_t(void *mutex); +typedef int sasl_mutex_unlock_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 *, + sasl_mutex_unlock_t *, sasl_mutex_free_t *); + +/***************************** + * Security preference types * + *****************************/ + +/* security layer strength factor -- an unsigned integer usable by the caller + * to specify approximate security layer strength desired. Roughly + * correlated to effective key length for encryption. + * 0 = no protection + * 1 = integrity protection only + * 40 = 40-bit DES or 40-bit RC2/RC4 + * 56 = DES + * 112 = triple-DES + * 128 = 128-bit RC2/RC4/BLOWFISH + * 256 = baseline AES + */ +typedef unsigned sasl_ssf_t; + +/* usage flags provided to sasl_server_new and sasl_client_new: + */ +#define SASL_SUCCESS_DATA 0x0004 /* server supports data on success */ +#define SASL_NEED_PROXY 0x0008 /* require a mech that allows proxying */ +#define SASL_NEED_HTTP 0x0010 /* require a mech that can do HTTP auth */ + +/*************************** + * Security Property Types * + ***************************/ + +/* Structure specifying the client or server's security policy + * and optional additional properties. + */ + +/* These are the various security flags apps can specify. */ +/* NOPLAINTEXT -- don't permit mechanisms susceptible to simple + * passive attack (e.g., PLAIN, LOGIN) + * NOACTIVE -- protection from active (non-dictionary) attacks + * during authentication exchange. + * Authenticates server. + * NODICTIONARY -- don't permit mechanisms susceptible to passive + * dictionary attack + * FORWARD_SECRECY -- require forward secrecy between sessions + * (breaking one won't help break next) + * NOANONYMOUS -- don't permit mechanisms that allow anonymous login + * PASS_CREDENTIALS -- require mechanisms which pass client + * credentials, and allow mechanisms which can pass + * credentials to do so + * MUTUAL_AUTH -- require mechanisms which provide mutual + * authentication + */ +#define SASL_SEC_NOPLAINTEXT 0x0001 +#define SASL_SEC_NOACTIVE 0x0002 +#define SASL_SEC_NODICTIONARY 0x0004 +#define SASL_SEC_FORWARD_SECRECY 0x0008 +#define SASL_SEC_NOANONYMOUS 0x0010 +#define SASL_SEC_PASS_CREDENTIALS 0x0020 +#define SASL_SEC_MUTUAL_AUTH 0x0040 +#define SASL_SEC_MAXIMUM 0xFFFF + +/* This is used when adding hash size to the security_flags field */ +/* NB: hash size is in bits */ +#define SASL_SET_HASH_STRENGTH_BITS(x) (((x) / 8) << 16) + +/* NB: This value is in bytes */ +#define SASL_GET_HASH_STRENGTH(x) ((x) >> 16) + +typedef struct sasl_security_properties +{ + /* security strength factor + * min_ssf = minimum acceptable final level + * max_ssf = maximum acceptable final level + */ + sasl_ssf_t min_ssf; + sasl_ssf_t max_ssf; + + /* Maximum security layer receive buffer size. + * 0=security layer not supported + */ + unsigned maxbufsize; + + /* bitfield for attacks to protect against */ + unsigned security_flags; + + /* NULL terminated array of additional property names, values */ + const char **property_names; + const char **property_values; +} sasl_security_properties_t; + +/****************** + * Callback types * + ******************/ + +/* + * Extensible type for a client/server callbacks + * id -- identifies callback type + * proc -- procedure call arguments vary based on id + * 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 { + /* Identifies the type of the callback function. + * Mechanisms must ignore callbacks with id's they don't recognize. + */ + unsigned long id; + int (*proc)(void); /* Callback function. Types of arguments vary by 'id' */ + void *context; +} sasl_callback_t; + +/* callback ids & functions: + */ +#define SASL_CB_LIST_END 0 /* end of list */ + +/* option reading callback -- this allows a SASL configuration to be + * encapsulated in the caller's configuration system. Some implementations + * may use default config file(s) if this is omitted. Configuration items + * may be plugin-specific and are arbitrary strings. + * + * inputs: + * context -- option context from callback record + * plugin_name -- name of plugin (NULL = general SASL option) + * option -- name of option + * output: + * result -- set to result which persists until next getopt in + * same thread, unchanged if option not found + * len -- length of result (may be NULL) + * returns: + * SASL_OK -- no error + * SASL_FAIL -- error + */ +typedef int sasl_getopt_t(void *context, const char *plugin_name, + const char *option, + const char **result, unsigned *len); +#define SASL_CB_GETOPT 1 + +/* Logging levels for use with the logging callback function. */ +#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 */ + +/* logging callback -- this allows plugins and the middleware to + * log operations they perform. + * inputs: + * context -- logging context from the callback record + * level -- logging level; see above + * message -- message to log + * returns: + * SASL_OK -- no error + * SASL_FAIL -- error + */ +typedef int sasl_log_t(void *context, + int level, + const char *message); +#define SASL_CB_LOG 2 + +/* getpath callback -- this allows applications to specify the + * colon-separated path to search for plugins (by default, + * taken from an implementation-specific location). + * inputs: + * context -- getpath context from the callback record + * outputs: + * path -- colon seperated path + * returns: + * SASL_OK -- no error + * SASL_FAIL -- error + */ +typedef int sasl_getpath_t(void *context, + const char **path); + +#define SASL_CB_GETPATH 3 + +/* verify file callback -- this allows applications to check if they + * want SASL to use files, file by file. This is intended to allow + * applications to sanity check the environment to make sure plugins + * or the configuration file can't be written to, etc. + * inputs: + * context -- verifypath context from the callback record + * file -- full path to file to verify + * type -- type of file to verify (see below) + + * returns: + * SASL_OK -- no error (file can safely be used) + * SASL_CONTINUE -- continue WITHOUT using this file + * SASL_FAIL -- error + */ + +/* these are the types of files libsasl will ask about */ +typedef enum { + SASL_VRFY_PLUGIN=0, /* a DLL/shared library plug-in */ + SASL_VRFY_CONF=1, /* a configuration file */ + 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 + +/* getconfpath callback -- this allows applications to specify the + * colon-separated path to search for config files (by default, + * taken from the SASL_CONF_PATH environment variable). + * inputs: + * context -- getconfpath context from the callback record + * outputs: + * path -- colon seperated path (allocated on the heap; the + * library will free it using the sasl_free_t * + * passed to sasl_set_callback, or the standard free() + * library call). + * returns: + * SASL_OK -- no error + * SASL_FAIL -- error + */ +typedef int sasl_getconfpath_t(void *context, + char **path); + +#define SASL_CB_GETCONFPATH 5 + +/* client/user interaction callbacks: + */ +/* Simple prompt -- result must persist until next call to getsimple on + * same connection or until connection context is disposed + * inputs: + * context -- context from callback structure + * id -- callback id + * outputs: + * result -- set to NUL terminated string + * NULL = user cancel + * len -- length of result + * returns SASL_OK + */ +typedef int sasl_getsimple_t(void *context, int id, + const char **result, unsigned *len); +#define SASL_CB_USER 0x4001 /* client user identity to login as */ +#define SASL_CB_AUTHNAME 0x4002 /* client authentication name */ +#define SASL_CB_LANGUAGE 0x4003 /* comma separated list of RFC 1766 + * language codes in order of preference + * to be used to localize client prompts + * or server error codes */ +#define SASL_CB_CNONCE 0x4007 /* caller supplies client-nonce + * primarily for testing purposes */ + +/* get a sasl_secret_t (plaintext password with length) + * 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 middleware + * will erase password data when it's done with it. + * returns SASL_OK + */ +typedef int sasl_getsecret_t(sasl_conn_t *conn, void *context, int id, + sasl_secret_t **psecret); +#define SASL_CB_PASS 0x4004 /* client passphrase-based secret */ + + +/* prompt for input in response to a challenge. + * input: + * context -- context from callback structure + * id -- callback id + * challenge -- server challenge + * output: + * result -- NUL terminated result, NULL = user cancel + * len -- length of result + * returns SASL_OK + */ +typedef int sasl_chalprompt_t(void *context, int id, + const char *challenge, + const char *prompt, const char *defresult, + const char **result, unsigned *len); +#define SASL_CB_ECHOPROMPT 0x4005 /* challenge and client enterred result */ +#define SASL_CB_NOECHOPROMPT 0x4006 /* challenge and client enterred result */ + +/* prompt (or autoselect) the realm to do authentication in. + * may get a list of valid realms. + * input: + * context -- context from callback structure + * id -- callback id + * availrealms -- available realms; string list; NULL terminated + * list may be empty. + * output: + * result -- NUL terminated realm; NULL is equivalent to "" + * returns SASL_OK + * result must persist until the next callback + */ +typedef int sasl_getrealm_t(void *context, int id, + const char **availrealms, + const char **result); +#define SASL_CB_GETREALM (0x4008) /* realm to attempt authentication in */ + +/* server callbacks: + */ + +/* improved callback to verify authorization; + * canonicalization now handled elsewhere + * conn -- connection context + * requested_user -- the identity/username to authorize (NUL terminated) + * rlen -- length of requested_user + * auth_identity -- the identity associated with the secret (NUL terminated) + * alen -- length of auth_identity + * default_realm -- default user realm, as passed to sasl_server_new if + * urlen -- length of default realm + * propctx -- auxiliary properties + * returns SASL_OK on success, + * SASL_NOAUTHZ or other SASL response on failure + */ +typedef int sasl_authorize_t(sasl_conn_t *conn, + void *context, + const char *requested_user, unsigned rlen, + const char *auth_identity, unsigned alen, + const char *def_realm, unsigned urlen, + struct propctx *propctx); +#define SASL_CB_PROXY_POLICY 0x8001 + +/* functions for "userdb" based plugins to call to get/set passwords. + * the location for the passwords is determined by the caller or middleware. + * plug-ins may get passwords from other locations. + */ + +/* callback to verify a plaintext password against the caller-supplied + * user database. This is necessary to allow additional <method>s for + * encoding of the userPassword property. + * user -- NUL terminated user name with user@realm syntax + * pass -- password to check (may not be NUL terminated) + * passlen -- length of password to check + * propctx -- auxiliary properties for user + */ +typedef int sasl_server_userdb_checkpass_t(sasl_conn_t *conn, + void *context, + const char *user, + const char *pass, + unsigned passlen, + struct propctx *propctx); +#define SASL_CB_SERVER_USERDB_CHECKPASS (0x8005) + +/* callback to store/change a plaintext password in the user database + * user -- NUL terminated user name with user@realm syntax + * pass -- password to store (may not be NUL terminated) + * 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 + +/* Combine the following with SASL_CU_AUTHID, if you don't want + to fail if auxprop returned SASL_NOUSER/SASL_NOMECH. */ +#define SASL_CU_EXTERNALLY_VERIFIED 0x04 + +#define SASL_CU_OVERRIDE 0x08 /* mapped to SASL_AUXPROP_OVERRIDE */ + +/* The following CU flags are passed "as is" down to auxprop lookup */ +#define SASL_CU_ASIS_MASK 0xFFF0 +/* NOTE: Keep in sync with SASL_AUXPROP_<XXX> flags */ +#define SASL_CU_VERIFY_AGAINST_HASH 0x10 + + +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 * + **********************************/ + +/* Types of paths to set (see sasl_set_path below). */ +#define SASL_PATH_TYPE_PLUGIN 0 +#define SASL_PATH_TYPE_CONFIG 1 + +/* a simpler way to set plugin path or configuration file path + * without the need to set sasl_getpath_t callback. + * + * This function can be called before sasl_server_init/sasl_client_init. + */ +LIBSASL_API int sasl_set_path (int path_type, char * path); + +/* get sasl library version information + * implementation is a vendor-defined string + * version is a vender-defined representation of the version #. + * + * This function is being deprecated in favor of sasl_version_info. */ +LIBSASL_API void sasl_version(const char **implementation, + int *version); + +/* Extended version of sasl_version(). + * + * This function is to be used + * for library version display and logging + * for bug workarounds in old library versions + * + * The sasl_version_info is not to be used for API feature detection. + * + * All parameters are optional. If NULL is specified, the value is not returned. + */ +LIBSASL_API void sasl_version_info (const char **implementation, + const char **version_string, + int *version_major, + int *version_minor, + int *version_step, + int *version_patch); + +/* dispose of all SASL plugins. Connection + * states have to be disposed of before calling this. + * + * This function is DEPRECATED in favour of sasl_server_done/ + * sasl_client_done. + */ +LIBSASL_API void sasl_done(void); + +/* dispose of all SASL plugins. Connection + * states have to be disposed of before calling this. + * This function should be called instead of sasl_done(), + whenever possible. + */ +LIBSASL_API int sasl_server_done(void); + +/* dispose of all SASL plugins. Connection + * states have to be disposed of before calling this. + * This function should be called instead of sasl_done(), + whenever possible. + */ +LIBSASL_API int sasl_client_done(void); + +/* dispose connection state, sets it to NULL + * checks for pointer to NULL + */ +LIBSASL_API void sasl_dispose(sasl_conn_t **pconn); + +/* translate an error number into a string + * input: + * saslerr -- the error number + * langlist -- comma separated list of RFC 1766 languages (may be NULL) + * results: + * outlang -- the language actually used (may be NULL if don't care) + * returns: + * the error message in UTF-8 (only the US-ASCII subset if langlist is NULL) + */ +LIBSASL_API const char *sasl_errstring(int saslerr, + const char *langlist, + 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 + * propnum -- property number + * pvalue -- pointer to value + * returns: + * SASL_OK -- no error + * SASL_NOTDONE -- property not available yet + * SASL_BADPARAM -- bad property number + */ +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_SSF 1 /* security layer security strength factor, + * if 0, call to sasl_encode, sasl_decode + * unnecessary */ +#define SASL_MAXOUTBUF 2 /* security layer max output buf unsigned */ +#define SASL_DEFUSERREALM 3 /* default realm passed to server_new */ + /* or set with setprop */ +#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 */ + +/* 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 + +/* a handle to any delegated credentials or NULL if none is present + * is returned by the mechanism. The user will probably need to know + * which mechanism was used to actually known how to make use of them + * currently only implemented for the gssapi mechanism */ +#define SASL_DELEGATEDCREDS 11 + +#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 */ +#define SASL_AUTHUSER 16 /* authentication/admin user */ +#define SASL_APPNAME 17 /* application name (used for logging/ + configuration), same as appname parameter + to sasl_server_init */ + +/* GSS-API credential handle for sasl_client_step() or sasl_server_step(). + * The application is responsible for releasing this credential handle. */ +#define SASL_GSS_CREDS 18 + +/* GSS name (gss_name_t) of the peer, as output by gss_inquire_context() + * or gss_accept_sec_context(). + * On server end this is similar to SASL_USERNAME, but the gss_name_t + * structure can contain additional attributes associated with the peer. + */ +#define SASL_GSS_PEER_NAME 19 + +/* Local GSS name (gss_name_t) as output by gss_inquire_context(). This + * is particularly useful for servers that respond to multiple names. */ +#define SASL_GSS_LOCAL_NAME 20 + +/* Channel binding information. Memory is managed by the caller. */ +typedef struct sasl_channel_binding { + const char *name; + int critical; + unsigned long len; + const unsigned char *data; +} sasl_channel_binding_t; + +#define SASL_CHANNEL_BINDING 21 + +/* HTTP Request (RFC 2616) - ONLY used for HTTP Digest Auth (RFC 2617) */ +typedef struct sasl_http_request { + const char *method; /* HTTP Method */ + const char *uri; /* request-URI */ + const unsigned char *entity; /* entity-body */ + unsigned long elen; /* entity-body length */ + unsigned non_persist; /* Is it a non-persistent connection? */ +} sasl_http_request_t; + +#define SASL_HTTP_REQUEST 22 + +/* set property in SASL connection state + * returns: + * SASL_OK -- value set + * SASL_BADPARAM -- invalid property or value + */ +LIBSASL_API int sasl_setprop(sasl_conn_t *conn, + int propnum, + const void *value); +#define SASL_SSF_EXTERNAL 100 /* external SSF active (sasl_ssf_t *) */ +#define SASL_SEC_PROPS 101 /* sasl_security_properties_t */ +#define SASL_AUTH_EXTERNAL 102 /* external authentication ID (const char *) */ + +/* If the SASL_AUTH_EXTERNAL value is non-NULL, then a special version of the + * EXTERNAL mechanism is enabled (one for server-embedded EXTERNAL mechanisms). + * 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 + * may pass NULL to precompute for some mechanisms prior to connect + * returns 1 if action taken, 0 if no action taken + */ +LIBSASL_API int sasl_idle(sasl_conn_t *conn); + +/************** + * Client API * + **************/ + +/* list of client interactions with user for caller to fill in + */ +typedef struct sasl_interact { + unsigned long id; /* same as client/user callback ID */ + const char *challenge; /* presented to user (e.g. OTP challenge) */ + const char *prompt; /* presented to user (e.g. "Username: ") */ + const char *defresult; /* default result string */ + const void *result; /* set to point to result */ + unsigned len; /* set to length of result */ +} sasl_interact_t; + +/* initialize the SASL client drivers + * callbacks -- base callbacks for all client connections; + * must include getopt callback + * returns: + * SASL_OK -- Success + * SASL_NOMEM -- Not enough memory + * SASL_BADVERS -- Mechanism version mismatch + * SASL_BADPARAM -- missing getopt callback or error in config file + * SASL_NOMECH -- No mechanisms available + * ... + */ +LIBSASL_API int sasl_client_init(const sasl_callback_t *callbacks); + +/* initialize a client exchange based on the specified mechanism + * service -- registered name of the service using SASL (e.g. "imap") + * 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 disabled) + * ipremoteport -- server IPv4/IPv6 domain literal string with port + * (if NULL, then mechanisms requiring IPaddr are disabled) + * prompt_supp -- list of client interactions supported + * may also include sasl_getopt_t context & call + * NULL prompt_supp = user/pass via SASL_INTERACT only + * NULL proc = interaction supported via SASL_INTERACT + * flags -- server usage flags (see above) + * in/out: + * pconn -- connection negotiation structure + * pointer to NULL => allocate new + * + * Returns: + * SASL_OK -- success + * SASL_NOMECH -- no mechanism meets requested properties + * SASL_NOMEM -- not enough memory + */ +LIBSASL_API int sasl_client_new(const char *service, + const char *serverFQDN, + const char *iplocalport, + const char *ipremoteport, + const sasl_callback_t *prompt_supp, + unsigned flags, + sasl_conn_t **pconn); + +/* select a mechanism for a connection + * mechlist -- mechanisms server has available (punctuation ignored) + * if NULL, then discard cached info and retry last mech + * output: + * 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 + * will be valid until next call to client_start/client_step + * NULL if mech doesn't include initial client challenge + * mech -- set to mechansm name of selected mechanism (may be NULL) + * + * Returns: + * SASL_OK -- success + * SASL_NOMEM -- not enough memory + * SASL_NOMECH -- no mechanism meets requested properties + * SASL_INTERACT -- user interaction needed to fill in prompt_need list + */ +LIBSASL_API int sasl_client_start(sasl_conn_t *conn, + const char *mechlist, + sasl_interact_t **prompt_need, + const char **clientout, + unsigned *clientoutlen, + const char **mech); + +/* do a single authentication step. + * serverin -- the server message received by the client, MUST have a NUL + * sentinel, not counted by serverinlen + * output: + * prompt_need -- on SASL_INTERACT, list of prompts needed to continue + * clientout -- the client response to send to the server + * will be valid until next call to client_start/client_step + * + * returns: + * SASL_OK -- success + * SASL_INTERACT -- user interaction needed to fill in prompt_need list + * SASL_BADPROT -- server protocol incorrect/cancelled + * SASL_BADSERV -- server failed mutual auth + */ +LIBSASL_API int sasl_client_step(sasl_conn_t *conn, + const char *serverin, + unsigned serverinlen, + sasl_interact_t **prompt_need, + const char **clientout, + unsigned *clientoutlen); + +/************** + * Server API * + **************/ + +/* initialize server drivers, done once per process + * callbacks -- callbacks for all server connections; must include + * getopt callback + * appname -- name of calling application (for lower level logging) + * results: + * state -- server state + * returns: + * SASL_OK -- success + * SASL_BADPARAM -- error in config file + * SASL_NOMEM -- memory failure + * SASL_BADVERS -- Mechanism version mismatch + */ +LIBSASL_API int sasl_server_init(const sasl_callback_t *callbacks, + 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 terminator. + */ + +/* create context for a single SASL connection + * service -- registered name of the service using SASL (e.g. "imap") + * serverFQDN -- Fully qualified domain name of server. NULL means use + * gethostname() or equivalent. + * Useful for multi-homed servers. + * user_realm -- permits multiple user realms on server, NULL = default + * iplocalport -- server IPv4/IPv6 domain literal string with port + * (if NULL, then mechanisms requiring IPaddr are disabled) + * ipremoteport -- client IPv4/IPv6 domain literal string with port + * (if NULL, then mechanisms requiring IPaddr are disabled) + * callbacks -- callbacks (e.g., authorization, lang, new getopt context) + * flags -- usage flags (see above) + * returns: + * pconn -- new connection context + * + * returns: + * SASL_OK -- success + * SASL_NOMEM -- not enough memory + */ +LIBSASL_API int sasl_server_new(const char *service, + const char *serverFQDN, + const char *user_realm, + const char *iplocalport, + const char *ipremoteport, + const sasl_callback_t *callbacks, + unsigned flags, + 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 + * conn -- the connection to list mechanisms for (either client + * or server) + * user -- restricts mechanisms to those available to that user + * (may be NULL, not used for client case) + * prefix -- appended to beginning of result + * sep -- appended between mechanisms + * suffix -- appended to end of result + * results: + * 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 + * pcount -- gets number of mechanisms, may be NULL + * + * returns: + * SASL_OK -- success + * SASL_NOMEM -- not enough memory + * SASL_NOMECH -- no enabled mechanisms + */ +LIBSASL_API int sasl_listmech(sasl_conn_t *conn, + const char *user, + const char *prefix, + const char *sep, + const char *suffix, + const char **result, + unsigned *plen, + int *pcount); + +/* start a mechanism exchange within a connection context + * mech -- the mechanism name client requested + * clientin -- client initial response (NUL terminated), NULL if empty + * clientinlen -- length of initial response + * serverout -- initial server challenge, NULL if done + * (library handles freeing this string) + * serveroutlen -- length of initial server challenge + * output: + * pconn -- the connection negotiation state on success + * + * Same returns as sasl_server_step() or + * SASL_NOMECH if mechanism not available. + */ +LIBSASL_API int sasl_server_start(sasl_conn_t *conn, + const char *mech, + const char *clientin, + unsigned clientinlen, + const char **serverout, + unsigned *serveroutlen); + +/* perform one step of the SASL exchange + * inputlen & input -- client data + * NULL on first step if no optional client step + * outputlen & output -- set to the server data to transmit + * to the client in the next step + * (library handles freeing this) + * + * returns: + * SASL_OK -- exchange is complete. + * SASL_CONTINUE -- indicates another step is necessary. + * SASL_TRANS -- entry for user exists, but not for mechanism + * and transition is possible + * SASL_BADPARAM -- service name needed + * SASL_BADPROT -- invalid input from client + * ... + */ +LIBSASL_API int sasl_server_step(sasl_conn_t *conn, + const char *clientin, + unsigned clientinlen, + const char **serverout, + unsigned *serveroutlen); + +/* 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 + * if user is NULL, check if plaintext passwords are enabled + * inputs: + * user -- user to query in current user_domain + * userlen -- length of username, 0 = strlen(user) + * pass -- plaintext password to check + * passlen -- length of password, 0 = strlen(pass) + * returns + * SASL_OK -- success + * SASL_NOMECH -- mechanism not supported + * SASL_NOVERIFY -- user found, but no verifier + * SASL_NOUSER -- user not found + */ +LIBSASL_API int sasl_checkpass(sasl_conn_t *conn, + const char *user, unsigned userlen, + const char *pass, unsigned passlen); + +/* check if a user exists on server + * conn -- connection context + * service -- registered name of the service using SASL (e.g. "imap") + * user_realm -- permits multiple user realms on server, NULL = default + * user -- NUL terminated user name + * + * returns: + * SASL_OK -- success + * SASL_DISABLED -- account disabled + * SASL_NOUSER -- user not found + * SASL_NOVERIFY -- user found, but no usable mechanism + * SASL_NOMECH -- no mechanisms enabled + * SASL_UNAVAIL -- remote authentication server unavailable, try again later + */ +LIBSASL_API int sasl_user_exists(sasl_conn_t *conn, + const char *service, + const char *user_realm, + const char *user); + +/* set the password for a user + * conn -- SASL connection + * user -- user name + * pass -- plaintext password, may be NULL to remove user + * passlen -- length of password, 0 = strlen(pass) + * oldpass -- NULL will sometimes work + * oldpasslen -- length of password, 0 = strlen(oldpass) + * flags -- see flags below + * + * returns: + * SASL_NOCHANGE -- proper entry already exists + * SASL_NOMECH -- no authdb supports password setting as configured + * SASL_NOVERIFY -- user exists, but no settable password present + * SASL_DISABLED -- account disabled + * SASL_PWLOCK -- password locked + * SASL_WEAKPASS -- password too weak for security policy + * SASL_NOUSERPASS -- user-supplied passwords not permitted + * SASL_FAIL -- OS error + * SASL_BADPARAM -- password too long + * SASL_OK -- successful + */ +LIBSASL_API int sasl_setpass(sasl_conn_t *conn, + const char *user, + const char *pass, unsigned passlen, + const char *oldpass, unsigned oldpasslen, + unsigned flags); +#define SASL_SET_CREATE 0x01 /* create a new entry for user */ +#define SASL_SET_DISABLE 0x02 /* disable user account */ +#define SASL_SET_NOPLAIN 0x04 /* do not store secret in plain text */ +#define SASL_SET_CURMECH_ONLY 0x08 /* set the mechanism specific password only. + fail if no current mechanism */ + +/********************************************************* + * Auxiliary Property Support -- added by cjn 1999-09-29 * + *********************************************************/ + +#define SASL_AUX_END NULL /* last auxiliary property */ + +#define SASL_AUX_ALL "*" /* A special flag to signal user deletion */ + +/* traditional Posix items (should be implemented on Posix systems) */ +#define SASL_AUX_PASSWORD_PROP "userPassword" /* User Password */ +#define SASL_AUX_PASSWORD "*" SASL_AUX_PASSWORD_PROP /* User Password (of authid) */ +#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); + +/* Store the set of auxiliary properties for the given user. + * Use functions in prop.h to set the content. + * + * conn connection context + * ctx property context from prop_new()/prop_request()/prop_set() + * user NUL terminated user + * + * Call with NULL 'ctx' to see if the backend allows storing properties. + * + * errors + * SASL_OK -- success + * SASL_NOMECH -- can not store some/all properties + * SASL_BADPARAM -- bad conn/ctx/user parameter + * SASL_NOMEM -- out of memory + * SASL_FAIL -- failed to store + */ +LIBSASL_API int sasl_auxprop_store(sasl_conn_t *conn, + struct propctx *ctx, const char *user); + +/********************** + * security layer API * + **********************/ + +/* 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: + * SASL_OK -- success (returns input if no layer negotiated) + * 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, + const char *input, unsigned inputlen, + const char **output, unsigned *outputlen); + +/* encode a block of data for transmission using security layer + * output is only valid until next call to sasl_encode or sasl_encodev + * returns: + * SASL_OK -- success (returns input if no layer negotiated) + * 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_encodev(sasl_conn_t *conn, + const struct iovec *invec, unsigned numiov, + const char **output, unsigned *outputlen); + +/* decode a block of data received using security layer + * returning the input buffer if there is no security layer. + * output is only valid until next call to sasl_decode + * + * if outputlen is 0 on return, than the value of output is undefined. + * + * returns: + * SASL_OK -- success (returns input if no layer negotiated) + * SASL_NOTDONE -- security layer negotiation not finished + * SASL_BADMAC -- bad message integrity check + */ +LIBSASL_API int sasl_decode(sasl_conn_t *conn, + const char *input, unsigned inputlen, + const char **output, unsigned *outputlen); + +#ifdef __cplusplus +} +#endif + +#endif /* SASL_H */ diff --git a/contrib/libs/sasl/include/sasl/prop.h b/contrib/libs/sasl/include/sasl/prop.h new file mode 100644 index 0000000000..bf091d67d8 --- /dev/null +++ b/contrib/libs/sasl/include/sasl/prop.h @@ -0,0 +1,170 @@ +/* prop.h -- property request/response management routines + * + * Author: Chris Newman + * Removal of implementation-specific details by: Rob Siemborski + * + * This is intended to be used to create a list of properties to request, + * and _then_ request values for all properties. Any change to the request + * list will discard any existing values. This assumption allows a very + * efficient and simple memory model. This was designed for SASL API auxiliary + * property support, but would be fine for other contexts where this property + * model is appropriate. + * + * The "struct propctx" is allocated by prop_new and is a fixed size structure. + * If a prop_init() call were added, it would be reasonable to embed a "struct + * propctx" in another structure. prop_new also allocates a pool of memory + * (in the vbase field) which will be used for an array of "struct propval" + * to list all the requested properties. + * + * Properties may be multi-valued. + */ + +#ifndef PROP_H +#define PROP_H 1 + +/* The following ifdef block is the standard way of creating macros + * which make exporting from a DLL simpler. All files within this DLL + * 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.) */ +# define LIBSASL_API extern + +/* Same as above, but used during a variable declaration. */ +# define LIBSASL_VAR extern + +/* the resulting structure for property values + */ +struct propval { + const char *name; /* name of property; NULL = end of list */ + /* same pointer used in request will be used here */ + const char **values; /* list of strings, values == NULL if property not + * found, *values == NULL if property found with + * no values */ + unsigned nvalues; /* total number of value strings */ + unsigned valsize; /* total size in characters of all value strings */ +}; + +/* + * private internal structure + */ +#define PROP_DEFAULT 4 /* default number of propvals to assume */ +struct propctx; + +#ifdef __cplusplus +extern "C" { +#endif + +/* create a property context + * estimate -- an estimate of the storage needed for requests & responses + * 0 will use module default + * returns a new property context on success and NULL on any error + */ +LIBSASL_API struct propctx *prop_new(unsigned estimate); + +/* create new propctx which duplicates the contents of an existing propctx + * returns SASL_OK on success + * possible other return values include: SASL_NOMEM, SASL_BADPARAM + */ +LIBSASL_API int prop_dup(struct propctx *src_ctx, struct propctx **dst_ctx); + +/* Add property names to request + * ctx -- context from prop_new() + * names -- list of property names; must persist until context freed + * or requests cleared (This extends to other contexts that + * are dup'ed from this one, and their children, etc) + * + * NOTE: may clear values from context as side-effect + * returns SASL_OK on success + * possible other return values include: SASL_NOMEM, SASL_BADPARAM + */ +LIBSASL_API int prop_request(struct propctx *ctx, const char **names); + +/* return array of struct propval from the context + * return value persists until next call to + * prop_request, prop_clear or prop_dispose on context + * + * returns NULL on error + */ +LIBSASL_API const struct propval *prop_get(struct propctx *ctx); + +/* Fill in an array of struct propval based on a list of property names + * return value persists until next call to + * prop_request, prop_clear or prop_dispose on context + * returns number of matching properties which were found (values != NULL) + * if a name requested here was never requested by a prop_request, then + * the name field of the associated vals entry will be set to NULL + * + * The vals array MUST be atleast as long as the names array. + * + * returns # of matching properties on success + * possible other return values include: SASL_BADPARAM + */ +LIBSASL_API int prop_getnames(struct propctx *ctx, const char **names, + struct propval *vals); + +/* clear values and optionally requests from property context + * ctx -- property context + * requests -- 0 = don't clear requests, 1 = clear requests + */ +LIBSASL_API void prop_clear(struct propctx *ctx, int requests); + +/* erase the value of a property + */ +LIBSASL_API void prop_erase(struct propctx *ctx, const char *name); + +/* dispose of property context + * ctx -- is disposed and set to NULL; noop if ctx or *ctx is NULL + */ +LIBSASL_API void prop_dispose(struct propctx **ctx); + + +/****fetcher interfaces****/ + +/* format the requested property names into a string + * ctx -- context from prop_new()/prop_request() + * sep -- separator between property names (unused if none requested) + * seplen -- length of separator, if < 0 then strlen(sep) will be used + * outbuf -- output buffer + * outmax -- maximum length of output buffer including NUL terminator + * outlen -- set to length of output string excluding NUL terminator + * returns SASL_OK on success + * returns SASL_BADPARAM or amount of additional space needed on failure + */ +LIBSASL_API int prop_format(struct propctx *ctx, const char *sep, int seplen, + char *outbuf, unsigned outmax, unsigned *outlen); + +/* add a property value to the context + * ctx -- context from prop_new()/prop_request() + * name -- name of property to which value will be added + * if NULL, add to the same name as previous prop_set/setvals call + * value -- a value for the property; will be copied into context + * if NULL, remove existing values + * vallen -- length of value, if <= 0 then strlen(value) will be used + * returns SASL_OK on success + * possible error return values include: SASL_BADPARAM, SASL_NOMEM + */ +LIBSASL_API int prop_set(struct propctx *ctx, const char *name, + const char *value, int vallen); + +/* set the values for a property + * ctx -- context from prop_new()/prop_request() + * name -- name of property to which value will be added + * if NULL, add to the same name as previous prop_set/setvals call + * values -- array of values, ending in NULL. Each value is a NUL terminated + * string + * returns SASL_OK on success + * possible error return values include: SASL_BADPARAM, SASL_NOMEM + */ +LIBSASL_API int prop_setvals(struct propctx *ctx, const char *name, + const char **values); + +#ifdef __cplusplus +} +#endif + +#endif /* PROP_H */ diff --git a/contrib/libs/sasl/include/sasl/sasl.h b/contrib/libs/sasl/include/sasl/sasl.h new file mode 100644 index 0000000000..dc04ca4714 --- /dev/null +++ b/contrib/libs/sasl/include/sasl/sasl.h @@ -0,0 +1,1332 @@ +/* This is a proposed C API for support of SASL + * + *********************************IMPORTANT******************************* + * send email to chris.newman@innosoft.com and cyrus-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: + * sasl_conn_t Context for a SASL connection negotiation + * sasl_ssf_t Security layer Strength Factor + * sasl_callback_t A typed client/server callback function and context + * sasl_interact_t A client interaction descriptor + * sasl_secret_t A client password + * sasl_rand_t Random data context structure + * sasl_security_properties_t An application's required security level + * + * Callbacks: + * sasl_getopt_t client/server: Get an option value + * sasl_logmsg_t client/server: Log message handler + * sasl_getsimple_t client: Get user/language list + * sasl_getsecret_t client: Get authentication secret + * sasl_chalprompt_t client: Display challenge and prompt for response + * + * Server only Callbacks: + * sasl_authorize_t user authorization policy callback + * sasl_getconfpath_t get path to search for config file + * 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: + * sasl_done Release all SASL global state + * sasl_dispose Connection done: Dispose of sasl_conn_t + * sasl_getprop Get property (e.g., user name, security layer info) + * sasl_setprop Set property (e.g., external ssf) + * sasl_errdetail Generate string from last error on connection + * sasl_errstring Translate sasl error code to a string + * sasl_encode Encode data to send using security layer + * sasl_decode Decode data received using security layer + * + * Utility functions: + * sasl_encode64 Encode data to send using MIME base64 encoding + * sasl_decode64 Decode data received using MIME base64 encoding + * sasl_erasebuffer Erase a buffer + * + * Client Function Summary: + * sasl_client_init Load and initialize client plug-ins (call once) + * sasl_client_new Initialize client connection context: sasl_conn_t + * sasl_client_start Select mechanism for connection + * sasl_client_step Perform one authentication step + * + * Server Function Summary + * sasl_server_init Load and initialize server plug-ins (call once) + * sasl_server_new Initialize server connection context: sasl_conn_t + * sasl_listmech Create list of available mechanisms + * sasl_server_start Begin an authentication exchange + * sasl_server_step Perform one authentication exchange step + * sasl_checkpass Check a plaintext passphrase + * 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_auxprop_request Request auxiliary properties + * sasl_auxprop_getctx Get auxiliary property context for connection + * sasl_auxprop_store Store a set of auxiliary properties + * + * Basic client model: + * 1. client calls sasl_client_init() at startup to load plug-ins + * 2. when connection formed, call sasl_client_new() + * 3. once list of supported mechanisms received from server, client + * calls sasl_client_start(). goto 4a + * 4. client calls sasl_client_step() + * [4a. If SASL_INTERACT, fill in prompts and goto 4 + * -- doesn't happen if callbacks provided] + * 4b. If SASL error, goto 7 or 3 + * 4c. If SASL_OK, continue or goto 6 if last server response was success + * 5. send message to server, wait for response + * 5a. On data or success with server response, goto 4 + * 5b. On failure goto 7 or 3 + * 5c. On success with no server response continue + * 6. continue with application protocol until connection closes + * call sasl_getprop/sasl_encode/sasl_decode() if using security layer + * 7. call sasl_dispose(), may return to step 2 + * 8. call sasl_done() when program terminates + * + * Basic Server model: + * 1. call sasl_server_init() at startup to load plug-ins + * 2. On connection, call sasl_server_new() + * 3. call sasl_listmech() and send list to client] + * 4. after client AUTH command, call sasl_server_start(), goto 5a + * 5. call sasl_server_step() + * 5a. If SASL_CONTINUE, output to client, wait response, repeat 5 + * 5b. If SASL error, then goto 7 + * 5c. If SASL_OK, move on + * 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 + * 7. call sasl_dispose(), may return to step 2 + * 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 +#define SASL_H 1 + +#include <stddef.h> /* For size_t */ + +/* Keep in sync with win32/common.mak */ +#define SASL_VERSION_MAJOR 2 +#define SASL_VERSION_MINOR 1 +#define SASL_VERSION_STEP 28 + +/* A convenience macro: same as was defined in the OpenLDAP LDAPDB */ +#define SASL_VERSION_FULL ((SASL_VERSION_MAJOR << 16) |\ + (SASL_VERSION_MINOR << 8) | SASL_VERSION_STEP) + +#include "prop.h" + +/************* + * Basic API * + *************/ + +/* SASL result codes: */ +#define SASL_CONTINUE 1 /* another step is needed in authentication */ +#define SASL_OK 0 /* successful result */ +#define SASL_FAIL -1 /* generic failure */ +#define SASL_NOMEM -2 /* memory shortage failure */ +#define SASL_BUFOVER -3 /* overflowed buffer */ +#define SASL_NOMECH -4 /* mechanism not supported */ +#define SASL_BADPROT -5 /* bad protocol / cancel */ +#define SASL_NOTDONE -6 /* can't request info until later in exchange */ +#define SASL_BADPARAM -7 /* invalid parameter supplied */ +#define SASL_TRYAGAIN -8 /* transient failure (e.g., weak key) */ +#define SASL_BADMAC -9 /* integrity check failed */ +#define SASL_NOTINIT -12 /* SASL library not initialized */ + /* -- client only codes -- */ +#define SASL_INTERACT 2 /* needs user interaction */ +#define SASL_BADSERV -10 /* server failed mutual authentication step */ +#define SASL_WRONGMECH -11 /* mechanism doesn't support requested feature */ + /* -- server only codes -- */ +#define SASL_BADAUTH -13 /* authentication failure */ +#define SASL_NOAUTHZ -14 /* authorization failure */ +#define SASL_TOOWEAK -15 /* mechanism too weak for this user */ +#define SASL_ENCRYPT -16 /* encryption needed to use mechanism */ +#define SASL_TRANS -17 /* One time use of a plaintext password will + enable requested mechanism for user */ +#define SASL_EXPIRED -18 /* passphrase expired, has to be reset */ +#define SASL_DISABLED -19 /* account disabled */ +#define SASL_NOUSER -20 /* user not found */ +#define SASL_BADVERS -23 /* version mismatch with plug-in */ +#define SASL_UNAVAIL -24 /* remote authentication server unavailable */ +#define SASL_NOVERIFY -26 /* user exists, but no verifier for user */ + /* -- codes for password setting -- */ +#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 */ +#define SASL_NEED_OLD_PASSWD -29 /* sasl_setpass needs old password in order + to perform password change */ +#define SASL_CONSTRAINT_VIOLAT -30 /* a property can't be stored, + because of some constrains/policy violation */ + +#define SASL_BADBINDING -32 /* channel binding failure */ +#define SASL_CONFIGERR -100 /* error when parsing configuration file */ + +/* max size of a sasl mechanism name */ +#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 + */ +typedef struct sasl_conn sasl_conn_t; + +/* Plain text password structure. + * len is the length of the password, data is the text. + */ +typedef struct sasl_secret { + unsigned long len; + unsigned char data[1]; /* variable sized */ +} sasl_secret_t; + +/* random data context structure + */ +typedef struct sasl_rand_s sasl_rand_t; + +#ifdef __cplusplus +extern "C" { +#endif + +/**************************** + * Configure Basic Services * + ****************************/ + +/* the following functions are used to adjust how allocation and mutexes work + * they must be called before all other SASL functions: + */ + +#include <sys/types.h> + +/* memory allocation functions which may optionally be replaced: + */ +typedef void *sasl_malloc_t(size_t); +typedef void *sasl_calloc_t(size_t, size_t); +typedef void *sasl_realloc_t(void *, size_t); +typedef void sasl_free_t(void *); + +LIBSASL_API void sasl_set_alloc(sasl_malloc_t *, + sasl_calloc_t *, + sasl_realloc_t *, + sasl_free_t *); + +/* mutex functions which may optionally be replaced: + * sasl_mutex_alloc allocates a mutex structure + * sasl_mutex_lock blocks until mutex locked + * returns -1 on deadlock or parameter error + * returns 0 on success + * sasl_mutex_unlock unlocks mutex if it's locked + * returns -1 if not locked or parameter error + * returns 0 on success + * sasl_mutex_free frees a mutex structure + */ +typedef void *sasl_mutex_alloc_t(void); +typedef int sasl_mutex_lock_t(void *mutex); +typedef int sasl_mutex_unlock_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 *, + sasl_mutex_unlock_t *, sasl_mutex_free_t *); + +/***************************** + * Security preference types * + *****************************/ + +/* security layer strength factor -- an unsigned integer usable by the caller + * to specify approximate security layer strength desired. Roughly + * correlated to effective key length for encryption. + * 0 = no protection + * 1 = integrity protection only + * 40 = 40-bit DES or 40-bit RC2/RC4 + * 56 = DES + * 112 = triple-DES + * 128 = 128-bit RC2/RC4/BLOWFISH + * 256 = baseline AES + */ +typedef unsigned sasl_ssf_t; + +/* usage flags provided to sasl_server_new and sasl_client_new: + */ +#define SASL_SUCCESS_DATA 0x0004 /* server supports data on success */ +#define SASL_NEED_PROXY 0x0008 /* require a mech that allows proxying */ +#define SASL_NEED_HTTP 0x0010 /* require a mech that can do HTTP auth */ + +/*************************** + * Security Property Types * + ***************************/ + +/* Structure specifying the client or server's security policy + * and optional additional properties. + */ + +/* These are the various security flags apps can specify. */ +/* NOPLAINTEXT -- don't permit mechanisms susceptible to simple + * passive attack (e.g., PLAIN, LOGIN) + * NOACTIVE -- protection from active (non-dictionary) attacks + * during authentication exchange. + * Authenticates server. + * NODICTIONARY -- don't permit mechanisms susceptible to passive + * dictionary attack + * FORWARD_SECRECY -- require forward secrecy between sessions + * (breaking one won't help break next) + * NOANONYMOUS -- don't permit mechanisms that allow anonymous login + * PASS_CREDENTIALS -- require mechanisms which pass client + * credentials, and allow mechanisms which can pass + * credentials to do so + * MUTUAL_AUTH -- require mechanisms which provide mutual + * authentication + */ +#define SASL_SEC_NOPLAINTEXT 0x0001 +#define SASL_SEC_NOACTIVE 0x0002 +#define SASL_SEC_NODICTIONARY 0x0004 +#define SASL_SEC_FORWARD_SECRECY 0x0008 +#define SASL_SEC_NOANONYMOUS 0x0010 +#define SASL_SEC_PASS_CREDENTIALS 0x0020 +#define SASL_SEC_MUTUAL_AUTH 0x0040 +#define SASL_SEC_MAXIMUM 0xFFFF + +/* This is used when adding hash size to the security_flags field */ +/* NB: hash size is in bits */ +#define SASL_SET_HASH_STRENGTH_BITS(x) (((x) / 8) << 16) + +/* NB: This value is in bytes */ +#define SASL_GET_HASH_STRENGTH(x) ((x) >> 16) + +typedef struct sasl_security_properties +{ + /* security strength factor + * min_ssf = minimum acceptable final level + * max_ssf = maximum acceptable final level + */ + sasl_ssf_t min_ssf; + sasl_ssf_t max_ssf; + + /* Maximum security layer receive buffer size. + * 0=security layer not supported + */ + unsigned maxbufsize; + + /* bitfield for attacks to protect against */ + unsigned security_flags; + + /* NULL terminated array of additional property names, values */ + const char **property_names; + const char **property_values; +} sasl_security_properties_t; + +/****************** + * Callback types * + ******************/ + +/* + * Extensible type for a client/server callbacks + * id -- identifies callback type + * proc -- procedure call arguments vary based on id + * 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 { + /* Identifies the type of the callback function. + * Mechanisms must ignore callbacks with id's they don't recognize. + */ + unsigned long id; + int (*proc)(void); /* Callback function. Types of arguments vary by 'id' */ + void *context; +} sasl_callback_t; + +/* callback ids & functions: + */ +#define SASL_CB_LIST_END 0 /* end of list */ + +/* option reading callback -- this allows a SASL configuration to be + * encapsulated in the caller's configuration system. Some implementations + * may use default config file(s) if this is omitted. Configuration items + * may be plugin-specific and are arbitrary strings. + * + * inputs: + * context -- option context from callback record + * plugin_name -- name of plugin (NULL = general SASL option) + * option -- name of option + * output: + * result -- set to result which persists until next getopt in + * same thread, unchanged if option not found + * len -- length of result (may be NULL) + * returns: + * SASL_OK -- no error + * SASL_FAIL -- error + */ +typedef int sasl_getopt_t(void *context, const char *plugin_name, + const char *option, + const char **result, unsigned *len); +#define SASL_CB_GETOPT 1 + +/* Logging levels for use with the logging callback function. */ +#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 */ + +/* logging callback -- this allows plugins and the middleware to + * log operations they perform. + * inputs: + * context -- logging context from the callback record + * level -- logging level; see above + * message -- message to log + * returns: + * SASL_OK -- no error + * SASL_FAIL -- error + */ +typedef int sasl_log_t(void *context, + int level, + const char *message); +#define SASL_CB_LOG 2 + +/* getpath callback -- this allows applications to specify the + * colon-separated path to search for plugins (by default, + * taken from an implementation-specific location). + * inputs: + * context -- getpath context from the callback record + * outputs: + * path -- colon seperated path + * returns: + * SASL_OK -- no error + * SASL_FAIL -- error + */ +typedef int sasl_getpath_t(void *context, + const char **path); + +#define SASL_CB_GETPATH 3 + +/* verify file callback -- this allows applications to check if they + * want SASL to use files, file by file. This is intended to allow + * applications to sanity check the environment to make sure plugins + * or the configuration file can't be written to, etc. + * inputs: + * context -- verifypath context from the callback record + * file -- full path to file to verify + * type -- type of file to verify (see below) + + * returns: + * SASL_OK -- no error (file can safely be used) + * SASL_CONTINUE -- continue WITHOUT using this file + * SASL_FAIL -- error + */ + +/* these are the types of files libsasl will ask about */ +typedef enum { + SASL_VRFY_PLUGIN=0, /* a DLL/shared library plug-in */ + SASL_VRFY_CONF=1, /* a configuration file */ + 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 + +/* getconfpath callback -- this allows applications to specify the + * colon-separated path to search for config files (by default, + * taken from the SASL_CONF_PATH environment variable). + * inputs: + * context -- getconfpath context from the callback record + * outputs: + * path -- colon seperated path (allocated on the heap; the + * library will free it using the sasl_free_t * + * passed to sasl_set_callback, or the standard free() + * library call). + * returns: + * SASL_OK -- no error + * SASL_FAIL -- error + */ +typedef int sasl_getconfpath_t(void *context, + char **path); + +#define SASL_CB_GETCONFPATH 5 + +/* client/user interaction callbacks: + */ +/* Simple prompt -- result must persist until next call to getsimple on + * same connection or until connection context is disposed + * inputs: + * context -- context from callback structure + * id -- callback id + * outputs: + * result -- set to NUL terminated string + * NULL = user cancel + * len -- length of result + * returns SASL_OK + */ +typedef int sasl_getsimple_t(void *context, int id, + const char **result, unsigned *len); +#define SASL_CB_USER 0x4001 /* client user identity to login as */ +#define SASL_CB_AUTHNAME 0x4002 /* client authentication name */ +#define SASL_CB_LANGUAGE 0x4003 /* comma separated list of RFC 1766 + * language codes in order of preference + * to be used to localize client prompts + * or server error codes */ +#define SASL_CB_CNONCE 0x4007 /* caller supplies client-nonce + * primarily for testing purposes */ + +/* get a sasl_secret_t (plaintext password with length) + * 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 middleware + * will erase password data when it's done with it. + * returns SASL_OK + */ +typedef int sasl_getsecret_t(sasl_conn_t *conn, void *context, int id, + sasl_secret_t **psecret); +#define SASL_CB_PASS 0x4004 /* client passphrase-based secret */ + + +/* prompt for input in response to a challenge. + * input: + * context -- context from callback structure + * id -- callback id + * challenge -- server challenge + * output: + * result -- NUL terminated result, NULL = user cancel + * len -- length of result + * returns SASL_OK + */ +typedef int sasl_chalprompt_t(void *context, int id, + const char *challenge, + const char *prompt, const char *defresult, + const char **result, unsigned *len); +#define SASL_CB_ECHOPROMPT 0x4005 /* challenge and client enterred result */ +#define SASL_CB_NOECHOPROMPT 0x4006 /* challenge and client enterred result */ + +/* prompt (or autoselect) the realm to do authentication in. + * may get a list of valid realms. + * input: + * context -- context from callback structure + * id -- callback id + * availrealms -- available realms; string list; NULL terminated + * list may be empty. + * output: + * result -- NUL terminated realm; NULL is equivalent to "" + * returns SASL_OK + * result must persist until the next callback + */ +typedef int sasl_getrealm_t(void *context, int id, + const char **availrealms, + const char **result); +#define SASL_CB_GETREALM (0x4008) /* realm to attempt authentication in */ + +/* server callbacks: + */ + +/* improved callback to verify authorization; + * canonicalization now handled elsewhere + * conn -- connection context + * requested_user -- the identity/username to authorize (NUL terminated) + * rlen -- length of requested_user + * auth_identity -- the identity associated with the secret (NUL terminated) + * alen -- length of auth_identity + * default_realm -- default user realm, as passed to sasl_server_new if + * urlen -- length of default realm + * propctx -- auxiliary properties + * returns SASL_OK on success, + * SASL_NOAUTHZ or other SASL response on failure + */ +typedef int sasl_authorize_t(sasl_conn_t *conn, + void *context, + const char *requested_user, unsigned rlen, + const char *auth_identity, unsigned alen, + const char *def_realm, unsigned urlen, + struct propctx *propctx); +#define SASL_CB_PROXY_POLICY 0x8001 + +/* functions for "userdb" based plugins to call to get/set passwords. + * the location for the passwords is determined by the caller or middleware. + * plug-ins may get passwords from other locations. + */ + +/* callback to verify a plaintext password against the caller-supplied + * user database. This is necessary to allow additional <method>s for + * encoding of the userPassword property. + * user -- NUL terminated user name with user@realm syntax + * pass -- password to check (may not be NUL terminated) + * passlen -- length of password to check + * propctx -- auxiliary properties for user + */ +typedef int sasl_server_userdb_checkpass_t(sasl_conn_t *conn, + void *context, + const char *user, + const char *pass, + unsigned passlen, + struct propctx *propctx); +#define SASL_CB_SERVER_USERDB_CHECKPASS (0x8005) + +/* callback to store/change a plaintext password in the user database + * user -- NUL terminated user name with user@realm syntax + * pass -- password to store (may not be NUL terminated) + * 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 + +/* Combine the following with SASL_CU_AUTHID, if you don't want + to fail if auxprop returned SASL_NOUSER/SASL_NOMECH. */ +#define SASL_CU_EXTERNALLY_VERIFIED 0x04 + +#define SASL_CU_OVERRIDE 0x08 /* mapped to SASL_AUXPROP_OVERRIDE */ + +/* The following CU flags are passed "as is" down to auxprop lookup */ +#define SASL_CU_ASIS_MASK 0xFFF0 +/* NOTE: Keep in sync with SASL_AUXPROP_<XXX> flags */ +#define SASL_CU_VERIFY_AGAINST_HASH 0x10 + + +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 * + **********************************/ + +/* Types of paths to set (see sasl_set_path below). */ +#define SASL_PATH_TYPE_PLUGIN 0 +#define SASL_PATH_TYPE_CONFIG 1 + +/* a simpler way to set plugin path or configuration file path + * without the need to set sasl_getpath_t callback. + * + * This function can be called before sasl_server_init/sasl_client_init. + */ +LIBSASL_API int sasl_set_path (int path_type, char * path); + +/* get sasl library version information + * implementation is a vendor-defined string + * version is a vender-defined representation of the version #. + * + * This function is being deprecated in favor of sasl_version_info. */ +LIBSASL_API void sasl_version(const char **implementation, + int *version); + +/* Extended version of sasl_version(). + * + * This function is to be used + * for library version display and logging + * for bug workarounds in old library versions + * + * The sasl_version_info is not to be used for API feature detection. + * + * All parameters are optional. If NULL is specified, the value is not returned. + */ +LIBSASL_API void sasl_version_info (const char **implementation, + const char **version_string, + int *version_major, + int *version_minor, + int *version_step, + int *version_patch); + +/* dispose of all SASL plugins. Connection + * states have to be disposed of before calling this. + * + * This function is DEPRECATED in favour of sasl_server_done/ + * sasl_client_done. + */ +LIBSASL_API void sasl_done(void); + +/* dispose of all SASL plugins. Connection + * states have to be disposed of before calling this. + * This function should be called instead of sasl_done(), + whenever possible. + */ +LIBSASL_API int sasl_server_done(void); + +/* dispose of all SASL plugins. Connection + * states have to be disposed of before calling this. + * This function should be called instead of sasl_done(), + whenever possible. + */ +LIBSASL_API int sasl_client_done(void); + +/* dispose connection state, sets it to NULL + * checks for pointer to NULL + */ +LIBSASL_API void sasl_dispose(sasl_conn_t **pconn); + +/* translate an error number into a string + * input: + * saslerr -- the error number + * langlist -- comma separated list of RFC 1766 languages (may be NULL) + * results: + * outlang -- the language actually used (may be NULL if don't care) + * returns: + * the error message in UTF-8 (only the US-ASCII subset if langlist is NULL) + */ +LIBSASL_API const char *sasl_errstring(int saslerr, + const char *langlist, + 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 + * propnum -- property number + * pvalue -- pointer to value + * returns: + * SASL_OK -- no error + * SASL_NOTDONE -- property not available yet + * SASL_BADPARAM -- bad property number + */ +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_SSF 1 /* security layer security strength factor, + * if 0, call to sasl_encode, sasl_decode + * unnecessary */ +#define SASL_MAXOUTBUF 2 /* security layer max output buf unsigned */ +#define SASL_DEFUSERREALM 3 /* default realm passed to server_new */ + /* or set with setprop */ +#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 */ + +/* 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 + +/* a handle to any delegated credentials or NULL if none is present + * is returned by the mechanism. The user will probably need to know + * which mechanism was used to actually known how to make use of them + * currently only implemented for the gssapi mechanism */ +#define SASL_DELEGATEDCREDS 11 + +#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 */ +#define SASL_AUTHUSER 16 /* authentication/admin user */ +#define SASL_APPNAME 17 /* application name (used for logging/ + configuration), same as appname parameter + to sasl_server_init */ + +/* GSS-API credential handle for sasl_client_step() or sasl_server_step(). + * The application is responsible for releasing this credential handle. */ +#define SASL_GSS_CREDS 18 + +/* GSS name (gss_name_t) of the peer, as output by gss_inquire_context() + * or gss_accept_sec_context(). + * On server end this is similar to SASL_USERNAME, but the gss_name_t + * structure can contain additional attributes associated with the peer. + */ +#define SASL_GSS_PEER_NAME 19 + +/* Local GSS name (gss_name_t) as output by gss_inquire_context(). This + * is particularly useful for servers that respond to multiple names. */ +#define SASL_GSS_LOCAL_NAME 20 + +/* Channel binding information. Memory is managed by the caller. */ +typedef struct sasl_channel_binding { + const char *name; + int critical; + unsigned long len; + const unsigned char *data; +} sasl_channel_binding_t; + +#define SASL_CHANNEL_BINDING 21 + +/* HTTP Request (RFC 2616) - ONLY used for HTTP Digest Auth (RFC 2617) */ +typedef struct sasl_http_request { + const char *method; /* HTTP Method */ + const char *uri; /* request-URI */ + const unsigned char *entity; /* entity-body */ + unsigned long elen; /* entity-body length */ + unsigned non_persist; /* Is it a non-persistent connection? */ +} sasl_http_request_t; + +#define SASL_HTTP_REQUEST 22 + +/* set property in SASL connection state + * returns: + * SASL_OK -- value set + * SASL_BADPARAM -- invalid property or value + */ +LIBSASL_API int sasl_setprop(sasl_conn_t *conn, + int propnum, + const void *value); +#define SASL_SSF_EXTERNAL 100 /* external SSF active (sasl_ssf_t *) */ +#define SASL_SEC_PROPS 101 /* sasl_security_properties_t */ +#define SASL_AUTH_EXTERNAL 102 /* external authentication ID (const char *) */ + +/* If the SASL_AUTH_EXTERNAL value is non-NULL, then a special version of the + * EXTERNAL mechanism is enabled (one for server-embedded EXTERNAL mechanisms). + * 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 + * may pass NULL to precompute for some mechanisms prior to connect + * returns 1 if action taken, 0 if no action taken + */ +LIBSASL_API int sasl_idle(sasl_conn_t *conn); + +/************** + * Client API * + **************/ + +/* list of client interactions with user for caller to fill in + */ +typedef struct sasl_interact { + unsigned long id; /* same as client/user callback ID */ + const char *challenge; /* presented to user (e.g. OTP challenge) */ + const char *prompt; /* presented to user (e.g. "Username: ") */ + const char *defresult; /* default result string */ + const void *result; /* set to point to result */ + unsigned len; /* set to length of result */ +} sasl_interact_t; + +/* initialize the SASL client drivers + * callbacks -- base callbacks for all client connections; + * must include getopt callback + * returns: + * SASL_OK -- Success + * SASL_NOMEM -- Not enough memory + * SASL_BADVERS -- Mechanism version mismatch + * SASL_BADPARAM -- missing getopt callback or error in config file + * SASL_NOMECH -- No mechanisms available + * ... + */ +LIBSASL_API int sasl_client_init(const sasl_callback_t *callbacks); + +/* initialize a client exchange based on the specified mechanism + * service -- registered name of the service using SASL (e.g. "imap") + * 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 disabled) + * ipremoteport -- server IPv4/IPv6 domain literal string with port + * (if NULL, then mechanisms requiring IPaddr are disabled) + * prompt_supp -- list of client interactions supported + * may also include sasl_getopt_t context & call + * NULL prompt_supp = user/pass via SASL_INTERACT only + * NULL proc = interaction supported via SASL_INTERACT + * flags -- server usage flags (see above) + * in/out: + * pconn -- connection negotiation structure + * pointer to NULL => allocate new + * + * Returns: + * SASL_OK -- success + * SASL_NOMECH -- no mechanism meets requested properties + * SASL_NOMEM -- not enough memory + */ +LIBSASL_API int sasl_client_new(const char *service, + const char *serverFQDN, + const char *iplocalport, + const char *ipremoteport, + const sasl_callback_t *prompt_supp, + unsigned flags, + sasl_conn_t **pconn); + +/* select a mechanism for a connection + * mechlist -- mechanisms server has available (punctuation ignored) + * if NULL, then discard cached info and retry last mech + * output: + * 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 + * will be valid until next call to client_start/client_step + * NULL if mech doesn't include initial client challenge + * mech -- set to mechansm name of selected mechanism (may be NULL) + * + * Returns: + * SASL_OK -- success + * SASL_NOMEM -- not enough memory + * SASL_NOMECH -- no mechanism meets requested properties + * SASL_INTERACT -- user interaction needed to fill in prompt_need list + */ +LIBSASL_API int sasl_client_start(sasl_conn_t *conn, + const char *mechlist, + sasl_interact_t **prompt_need, + const char **clientout, + unsigned *clientoutlen, + const char **mech); + +/* do a single authentication step. + * serverin -- the server message received by the client, MUST have a NUL + * sentinel, not counted by serverinlen + * output: + * prompt_need -- on SASL_INTERACT, list of prompts needed to continue + * clientout -- the client response to send to the server + * will be valid until next call to client_start/client_step + * + * returns: + * SASL_OK -- success + * SASL_INTERACT -- user interaction needed to fill in prompt_need list + * SASL_BADPROT -- server protocol incorrect/cancelled + * SASL_BADSERV -- server failed mutual auth + */ +LIBSASL_API int sasl_client_step(sasl_conn_t *conn, + const char *serverin, + unsigned serverinlen, + sasl_interact_t **prompt_need, + const char **clientout, + unsigned *clientoutlen); + +/************** + * Server API * + **************/ + +/* initialize server drivers, done once per process + * callbacks -- callbacks for all server connections; must include + * getopt callback + * appname -- name of calling application (for lower level logging) + * results: + * state -- server state + * returns: + * SASL_OK -- success + * SASL_BADPARAM -- error in config file + * SASL_NOMEM -- memory failure + * SASL_BADVERS -- Mechanism version mismatch + */ +LIBSASL_API int sasl_server_init(const sasl_callback_t *callbacks, + 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 terminator. + */ + +/* create context for a single SASL connection + * service -- registered name of the service using SASL (e.g. "imap") + * serverFQDN -- Fully qualified domain name of server. NULL means use + * gethostname() or equivalent. + * Useful for multi-homed servers. + * user_realm -- permits multiple user realms on server, NULL = default + * iplocalport -- server IPv4/IPv6 domain literal string with port + * (if NULL, then mechanisms requiring IPaddr are disabled) + * ipremoteport -- client IPv4/IPv6 domain literal string with port + * (if NULL, then mechanisms requiring IPaddr are disabled) + * callbacks -- callbacks (e.g., authorization, lang, new getopt context) + * flags -- usage flags (see above) + * returns: + * pconn -- new connection context + * + * returns: + * SASL_OK -- success + * SASL_NOMEM -- not enough memory + */ +LIBSASL_API int sasl_server_new(const char *service, + const char *serverFQDN, + const char *user_realm, + const char *iplocalport, + const char *ipremoteport, + const sasl_callback_t *callbacks, + unsigned flags, + 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 + * conn -- the connection to list mechanisms for (either client + * or server) + * user -- restricts mechanisms to those available to that user + * (may be NULL, not used for client case) + * prefix -- appended to beginning of result + * sep -- appended between mechanisms + * suffix -- appended to end of result + * results: + * 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 + * pcount -- gets number of mechanisms, may be NULL + * + * returns: + * SASL_OK -- success + * SASL_NOMEM -- not enough memory + * SASL_NOMECH -- no enabled mechanisms + */ +LIBSASL_API int sasl_listmech(sasl_conn_t *conn, + const char *user, + const char *prefix, + const char *sep, + const char *suffix, + const char **result, + unsigned *plen, + int *pcount); + +/* start a mechanism exchange within a connection context + * mech -- the mechanism name client requested + * clientin -- client initial response (NUL terminated), NULL if empty + * clientinlen -- length of initial response + * serverout -- initial server challenge, NULL if done + * (library handles freeing this string) + * serveroutlen -- length of initial server challenge + * output: + * pconn -- the connection negotiation state on success + * + * Same returns as sasl_server_step() or + * SASL_NOMECH if mechanism not available. + */ +LIBSASL_API int sasl_server_start(sasl_conn_t *conn, + const char *mech, + const char *clientin, + unsigned clientinlen, + const char **serverout, + unsigned *serveroutlen); + +/* perform one step of the SASL exchange + * inputlen & input -- client data + * NULL on first step if no optional client step + * outputlen & output -- set to the server data to transmit + * to the client in the next step + * (library handles freeing this) + * + * returns: + * SASL_OK -- exchange is complete. + * SASL_CONTINUE -- indicates another step is necessary. + * SASL_TRANS -- entry for user exists, but not for mechanism + * and transition is possible + * SASL_BADPARAM -- service name needed + * SASL_BADPROT -- invalid input from client + * ... + */ +LIBSASL_API int sasl_server_step(sasl_conn_t *conn, + const char *clientin, + unsigned clientinlen, + const char **serverout, + unsigned *serveroutlen); + +/* 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 + * if user is NULL, check if plaintext passwords are enabled + * inputs: + * user -- user to query in current user_domain + * userlen -- length of username, 0 = strlen(user) + * pass -- plaintext password to check + * passlen -- length of password, 0 = strlen(pass) + * returns + * SASL_OK -- success + * SASL_NOMECH -- mechanism not supported + * SASL_NOVERIFY -- user found, but no verifier + * SASL_NOUSER -- user not found + */ +LIBSASL_API int sasl_checkpass(sasl_conn_t *conn, + const char *user, unsigned userlen, + const char *pass, unsigned passlen); + +/* check if a user exists on server + * conn -- connection context + * service -- registered name of the service using SASL (e.g. "imap") + * user_realm -- permits multiple user realms on server, NULL = default + * user -- NUL terminated user name + * + * returns: + * SASL_OK -- success + * SASL_DISABLED -- account disabled + * SASL_NOUSER -- user not found + * SASL_NOVERIFY -- user found, but no usable mechanism + * SASL_NOMECH -- no mechanisms enabled + * SASL_UNAVAIL -- remote authentication server unavailable, try again later + */ +LIBSASL_API int sasl_user_exists(sasl_conn_t *conn, + const char *service, + const char *user_realm, + const char *user); + +/* set the password for a user + * conn -- SASL connection + * user -- user name + * pass -- plaintext password, may be NULL to remove user + * passlen -- length of password, 0 = strlen(pass) + * oldpass -- NULL will sometimes work + * oldpasslen -- length of password, 0 = strlen(oldpass) + * flags -- see flags below + * + * returns: + * SASL_NOCHANGE -- proper entry already exists + * SASL_NOMECH -- no authdb supports password setting as configured + * SASL_NOVERIFY -- user exists, but no settable password present + * SASL_DISABLED -- account disabled + * SASL_PWLOCK -- password locked + * SASL_WEAKPASS -- password too weak for security policy + * SASL_NOUSERPASS -- user-supplied passwords not permitted + * SASL_FAIL -- OS error + * SASL_BADPARAM -- password too long + * SASL_OK -- successful + */ +LIBSASL_API int sasl_setpass(sasl_conn_t *conn, + const char *user, + const char *pass, unsigned passlen, + const char *oldpass, unsigned oldpasslen, + unsigned flags); +#define SASL_SET_CREATE 0x01 /* create a new entry for user */ +#define SASL_SET_DISABLE 0x02 /* disable user account */ +#define SASL_SET_NOPLAIN 0x04 /* do not store secret in plain text */ +#define SASL_SET_CURMECH_ONLY 0x08 /* set the mechanism specific password only. + fail if no current mechanism */ + +/********************************************************* + * Auxiliary Property Support -- added by cjn 1999-09-29 * + *********************************************************/ + +#define SASL_AUX_END NULL /* last auxiliary property */ + +#define SASL_AUX_ALL "*" /* A special flag to signal user deletion */ + +/* traditional Posix items (should be implemented on Posix systems) */ +#define SASL_AUX_PASSWORD_PROP "userPassword" /* User Password */ +#define SASL_AUX_PASSWORD "*" SASL_AUX_PASSWORD_PROP /* User Password (of authid) */ +#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); + +/* Store the set of auxiliary properties for the given user. + * Use functions in prop.h to set the content. + * + * conn connection context + * ctx property context from prop_new()/prop_request()/prop_set() + * user NUL terminated user + * + * Call with NULL 'ctx' to see if the backend allows storing properties. + * + * errors + * SASL_OK -- success + * SASL_NOMECH -- can not store some/all properties + * SASL_BADPARAM -- bad conn/ctx/user parameter + * SASL_NOMEM -- out of memory + * SASL_FAIL -- failed to store + */ +LIBSASL_API int sasl_auxprop_store(sasl_conn_t *conn, + struct propctx *ctx, const char *user); + +/********************** + * security layer API * + **********************/ + +/* 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: + * SASL_OK -- success (returns input if no layer negotiated) + * 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, + const char *input, unsigned inputlen, + const char **output, unsigned *outputlen); + +/* encode a block of data for transmission using security layer + * output is only valid until next call to sasl_encode or sasl_encodev + * returns: + * SASL_OK -- success (returns input if no layer negotiated) + * 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_encodev(sasl_conn_t *conn, + const struct iovec *invec, unsigned numiov, + const char **output, unsigned *outputlen); + +/* decode a block of data received using security layer + * returning the input buffer if there is no security layer. + * output is only valid until next call to sasl_decode + * + * if outputlen is 0 on return, than the value of output is undefined. + * + * returns: + * SASL_OK -- success (returns input if no layer negotiated) + * SASL_NOTDONE -- security layer negotiation not finished + * SASL_BADMAC -- bad message integrity check + */ +LIBSASL_API int sasl_decode(sasl_conn_t *conn, + const char *input, unsigned inputlen, + const char **output, unsigned *outputlen); + +#ifdef __cplusplus +} +#endif + +#endif /* SASL_H */ diff --git a/contrib/libs/sasl/include/saslplug.h b/contrib/libs/sasl/include/saslplug.h new file mode 100644 index 0000000000..ab79e68cf6 --- /dev/null +++ b/contrib/libs/sasl/include/saslplug.h @@ -0,0 +1,986 @@ +/* saslplug.h -- API for SASL plug-ins + */ + +#ifndef SASLPLUG_H +#define SASLPLUG_H 1 + +#ifndef MD5GLOBAL_H +#include "md5global.h" +#endif +#ifndef MD5_H +#include "md5.h" +#endif +#ifndef HMAC_MD5_H +#include "hmac-md5.h" +#endif +#ifndef PROP_H +#include "prop.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* callback to lookup a sasl_callback_t for a connection + * input: + * conn -- the connection to lookup a callback for + * callbacknum -- the number of the callback + * output: + * pproc -- pointer to the callback function (set to NULL on failure) + * pcontext -- pointer to the callback context (set to NULL on failure) + * returns: + * SASL_OK -- no error + * SASL_FAIL -- unable to find a callback of the requested type + * SASL_INTERACT -- caller must use interaction to get data + */ +typedef int (*sasl_callback_ft)(void); +typedef int sasl_getcallback_t(sasl_conn_t *conn, + unsigned long callbackid, + sasl_callback_ft * pproc, + void **pcontext); + +/* The sasl_utils structure will remain backwards compatible unless + * the SASL_*_PLUG_VERSION is changed incompatibly + * higher SASL_UTILS_VERSION numbers indicate more functions are available + */ +#define SASL_UTILS_VERSION 4 + +/* utility function set for plug-ins + */ +typedef struct sasl_utils { + int version; + + /* contexts */ + sasl_conn_t *conn; + sasl_rand_t *rpool; + void *getopt_context; + + /* option function */ + sasl_getopt_t *getopt; + + /* allocation functions: */ + sasl_malloc_t *malloc; + sasl_calloc_t *calloc; + sasl_realloc_t *realloc; + sasl_free_t *free; + + /* mutex functions: */ + sasl_mutex_alloc_t *mutex_alloc; + sasl_mutex_lock_t *mutex_lock; + sasl_mutex_unlock_t *mutex_unlock; + sasl_mutex_free_t *mutex_free; + + /* MD5 hash and HMAC functions */ + void (*MD5Init)(MD5_CTX *); + void (*MD5Update)(MD5_CTX *, const unsigned char *text, unsigned int len); + void (*MD5Final)(unsigned char [16], MD5_CTX *); + void (*hmac_md5)(const unsigned char *text, int text_len, + const unsigned char *key, int key_len, + unsigned char [16]); + 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 */ + void (*hmac_md5_final)(unsigned char [16], HMAC_MD5_CTX *); + void (*hmac_md5_precalc)(HMAC_MD5_STATE *, + const unsigned char *key, int len); + void (*hmac_md5_import)(HMAC_MD5_CTX *, HMAC_MD5_STATE *); + + /* mechanism utility functions (same as above): */ + int (*mkchal)(sasl_conn_t *conn, char *buf, unsigned maxlen, + unsigned hostflag); + int (*utf8verify)(const char *str, unsigned len); + void (*rand)(sasl_rand_t *rpool, char *buf, unsigned len); + void (*churn)(sasl_rand_t *rpool, const char *data, unsigned len); + + /* 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 to + * set up a lightweight encryption layer just for sending a password. + */ + int (*checkpass)(sasl_conn_t *conn, + const char *user, unsigned userlen, + const char *pass, unsigned passlen); + + /* 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 */ + sasl_getcallback_t *getcallback; + + /* format a message and then pass it to the SASL_CB_LOG callback + * + * use syslog()-style formatting (printf with %m as a human readable text + * (strerror()) for the error specified as the parameter). + * The implementation may use a fixed size buffer not smaller + * than 512 octets if it securely truncates the message. + * + * level is a SASL_LOG_* level (see sasl.h) + */ + void (*log)(sasl_conn_t *conn, int level, const char *fmt, ...) __attribute__((format(printf, 3, 4))); + + /* callback to sasl_seterror() */ + void (*seterror)(sasl_conn_t *conn, unsigned flags, const char *fmt, ...) __attribute__((format(printf, 3, 4))); + + /* spare function pointer */ + int *(*spare_fptr)(void); + + /* 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); + int (*auxprop_store)(sasl_conn_t *conn, + struct propctx *ctx, const char *user); + + /* for additions which don't require a version upgrade; set to 0 */ + int (*spare_fptr1)(void); + int (*spare_fptr2)(void); +} sasl_utils_t; + +/* + * output parameters from SASL API + * + * created / destroyed by the glue code, though probably filled in + * by a combination of the plugin, the glue code, and the canon_user callback. + * + */ +typedef struct sasl_out_params { + unsigned doneflag; /* exchange complete */ + + const char *user; /* canonicalized user name */ + const char *authid; /* canonicalized authentication id */ + + unsigned ulen; /* length of canonicalized user name */ + unsigned alen; /* length of canonicalized authid */ + + /* security layer information */ + unsigned maxoutbuf; /* Maximum buffer size, which will + produce buffer no bigger than the + negotiated SASL maximum buffer size */ + 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; + int (*encode)(void *context, const struct iovec *invec, unsigned numiov, + const char **output, unsigned *outputlen); + void *decode_context; + int (*decode)(void *context, const char *input, unsigned inputlen, + const char **output, unsigned *outputlen); + + /* Pointer to delegated (client's) credentials, if supported by + the SASL mechanism */ + void *client_creds; + + /* for additions which don't require a version upgrade; set to 0 */ + const void *gss_peer_name; + const void *gss_local_name; + const char *cbindingname; /* channel binding name from packet */ + int (*spare_fptr1)(void); + int (*spare_fptr2)(void); + unsigned int cbindingdisp; /* channel binding disposition from client */ + int spare_int2; + int spare_int3; + int spare_int4; + + /* set to 0 initially, this allows a plugin with extended parameters + * to work with an older framework by updating version as parameters + * are added. + */ + int param_version; +} sasl_out_params_t; + + + +/* Used by both client and server side plugins */ +typedef enum { + SASL_INFO_LIST_START = 0, + SASL_INFO_LIST_MECH, + SASL_INFO_LIST_END +} sasl_info_callback_stage_t; + +/****************************** + * Channel binding macros ** + ******************************/ + +typedef enum { + SASL_CB_DISP_NONE = 0, /* client did not support CB */ + SASL_CB_DISP_WANT, /* client supports CB, thinks server does not */ + SASL_CB_DISP_USED /* client supports and used CB */ +} sasl_cbinding_disp_t; + +/* TRUE if channel binding is non-NULL */ +#define SASL_CB_PRESENT(params) ((params)->cbinding != NULL) +/* TRUE if channel binding is marked critical */ +#define SASL_CB_CRITICAL(params) (SASL_CB_PRESENT(params) && \ + (params)->cbinding->critical) + +/****************************** + * Client Mechanism Functions * + ******************************/ + +/* + * input parameters to client SASL plugin + * + * created / destroyed by the glue code + * + */ +typedef struct sasl_client_params { + const char *service; /* service name */ + const char *serverFQDN; /* server fully qualified domain name */ + const char *clientFQDN; /* client's fully qualified domain name */ + 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 *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 */ + sasl_security_properties_t props; + sasl_ssf_t external_ssf; /* external SSF active */ + + /* for additions which don't require a version upgrade; set to 0 */ + const void *gss_creds; /* GSS credential handle */ + const sasl_channel_binding_t *cbinding; /* client channel binding */ + const sasl_http_request_t *http_request;/* HTTP Digest request method */ + 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 terminated) + * 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)(void); + + unsigned int cbindingdisp; + 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 + * to work with an older framework by updating version as parameters + * are added. + */ + int param_version; +} 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 handle the client-first situation internally. + */ +#define SASL_FEAT_SERVER_FIRST 0x0010 + +/* This plugin allows proxying */ +#define SASL_FEAT_ALLOWS_PROXY 0x0020 + +/* server plugin don't use cleartext userPassword attribute */ +#define SASL_FEAT_DONTUSE_USERPASSWD 0x0080 + +/* Underlying mechanism uses GSS framing */ +#define SASL_FEAT_GSS_FRAMING 0x0100 + +/* Underlying mechanism supports channel binding */ +#define SASL_FEAT_CHANNEL_BINDING 0x0800 + +/* This plugin can be used for HTTP authentication */ +#define SASL_FEAT_SUPPORTS_HTTP 0x1000 + +/* client plug-in features */ +#define SASL_FEAT_NEEDSERVERFQDN 0x0001 + +/* a C object for a client mechanism + */ +typedef struct sasl_client_plug { + /* mechanism name */ + const char *mech_name; + + /* best mech additional security layer strength factor */ + sasl_ssf_t max_ssf; + + /* best security flags, as defined in sasl_security_properties_t */ + unsigned security_flags; + + /* features of plugin */ + unsigned features; + + /* required prompt ids, NULL = user/pass only */ + const unsigned long *required_prompts; + + /* global state for mechanism */ + void *glob_context; + + /* create context for mechanism, using params supplied + * glob_context -- from above + * params -- params from sasl_client_new + * conn_context -- context for one connection + * returns: + * SASL_OK -- success + * SASL_NOMEM -- not enough memory + * SASL_WRONGMECH -- mech doesn't support security params + */ + int (*mech_new)(void *glob_context, + sasl_client_params_t *cparams, + void **conn_context); + + /* perform one step of exchange. NULL is passed for serverin on + * first step. + * returns: + * SASL_OK -- success + * SASL_INTERACT -- user interaction needed to fill in prompts + * SASL_BADPROT -- server protocol incorrect/cancelled + * SASL_BADSERV -- server failed mutual auth + */ + int (*mech_step)(void *conn_context, + sasl_client_params_t *cparams, + const char *serverin, + unsigned serverinlen, + sasl_interact_t **prompt_need, + const char **clientout, + unsigned *clientoutlen, + sasl_out_params_t *oparams); + + /* dispose of connection context from mech_new + */ + void (*mech_dispose)(void *conn_context, const sasl_utils_t *utils); + + /* free all global space used by mechanism + * mech_dispose must be called on all mechanisms first + */ + void (*mech_free)(void *glob_context, const sasl_utils_t *utils); + + /* 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); + + /* for additions which don't require a version upgrade; set to 0 */ + int (*spare_fptr1)(void); + int (*spare_fptr2)(void); +} sasl_client_plug_t; + +#define SASL_CLIENT_PLUG_VERSION 4 + +/* plug-in entry point: + * utils -- utility callback functions + * max_version -- highest client plug version supported + * returns: + * out_version -- client plug version of result + * pluglist -- list of mechanism plug-ins + * plugcount -- number of mechanism plug-ins + * results: + * SASL_OK -- success + * SASL_NOMEM -- failure + * SASL_BADVERS -- max_version too small + * SASL_BADPARAM -- bad config string + * ... + */ +typedef int sasl_client_plug_init_t(const sasl_utils_t *utils, + int max_version, + int *out_version, + sasl_client_plug_t **pluglist, + int *plugcount); + + +/* add a client plug-in + */ +LIBSASL_API int sasl_client_add_plugin(const char *plugname, + sasl_client_plug_init_t *cplugfunc); + +typedef struct client_sasl_mechanism +{ + int version; + + char *plugname; + const sasl_client_plug_t *plug; +} client_sasl_mechanism_t; + +typedef void sasl_client_info_callback_t (client_sasl_mechanism_t *m, + sasl_info_callback_stage_t stage, + void *rock); + +/* Dump information about available client plugins */ +LIBSASL_API int sasl_client_plugin_info (const char *mech_list, + sasl_client_info_callback_t *info_cb, + void *info_cb_rock); + + +/******************** + * Server Functions * + ********************/ + +/* log message formatting routine */ +typedef void sasl_logmsg_p(sasl_conn_t *conn, const char *fmt, ...) __attribute__((format(printf, 2, 3))); + +/* + * input parameters to server SASL plugin + * + * created / destroyed by the glue code + * + */ +typedef struct sasl_server_params { + const char *service; /* NULL = default service for user_exists + and setpass */ + const char *appname; /* name of calling application */ + const char *serverFQDN; /* server default fully qualified domain name + * (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 */ + sasl_security_properties_t props; + sasl_ssf_t external_ssf; /* external SSF active */ + + /* Pointer to the function which takes the plaintext passphrase and + * transitions a user to non-plaintext mechanisms via setpass calls. + * (NULL = auto transition not enabled/supported) + * + * If passlen is 0, it defaults to strlen(pass). + * returns 0 if no entry added, 1 if entry added + */ + int (*transition)(sasl_conn_t *conn, const char *pass, unsigned passlen); + + /* Canonicalize a user name from on-wire to internal format + * added cjn 1999-09-21 + * Must be called once user name acquired if canon_user is non-NULL. + * conn connection context + * user user name from wire protocol (need not be NUL terminated) + * 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 */ + const void *gss_creds; /* GSS credential handle */ + const sasl_channel_binding_t *cbinding; /* server channel binding */ + const sasl_http_request_t *http_request;/* HTTP Digest request method */ + void *spare_ptr4; + int (*spare_fptr1)(void); + int (*spare_fptr2)(void); + 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 + * to work with an older framework by updating version as parameters + * are added. + */ + int param_version; +} 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: + */ +/* SASL_SET_CREATE create user if pass non-NULL */ +/* SASL_SET_DISABLE disable user */ +#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 callbacks + * required by plug-in */ + +/* a C object for a server mechanism + */ +typedef struct sasl_server_plug { + /* mechanism name */ + const char *mech_name; + + /* best mech additional security layer strength factor */ + sasl_ssf_t max_ssf; + + /* best security flags, as defined in sasl_security_properties_t */ + unsigned security_flags; + + /* features of plugin */ + unsigned features; + + /* global state for mechanism */ + void *glob_context; + + /* create a new mechanism handler + * glob_context -- global context + * sparams -- server config params + * challenge -- server challenge from previous instance or NULL + * challen -- length of challenge from previous instance or 0 + * out: + * conn_context -- connection context + * errinfo -- error information + * + * returns: + * SASL_OK -- successfully created mech instance + * SASL_* -- any other server error code + */ + int (*mech_new)(void *glob_context, + sasl_server_params_t *sparams, + const char *challenge, + unsigned challen, + void **conn_context); + + /* perform one step in exchange + * + * returns: + * SASL_OK -- success, all done + * SASL_CONTINUE -- success, one more round trip + * SASL_* -- any other server error code + */ + int (*mech_step)(void *conn_context, + sasl_server_params_t *sparams, + const char *clientin, + unsigned clientinlen, + const char **serverout, + unsigned *serveroutlen, + sasl_out_params_t *oparams); + + /* dispose of a connection state + */ + void (*mech_dispose)(void *conn_context, const sasl_utils_t *utils); + + /* free global state for mechanism + * mech_dispose must be called on all mechanisms first + */ + void (*mech_free)(void *glob_context, const sasl_utils_t *utils); + + /* set a password (optional) + * glob_context -- global context + * sparams -- service, middleware utilities, etc. props ignored + * user -- user name + * pass -- password/passphrase (NULL = disable/remove/delete) + * passlen -- length of password/passphrase + * oldpass -- old password/passphrase (NULL = transition) + * oldpasslen -- length of password/passphrase + * flags -- see above + * + * returns: + * SASL_NOCHANGE -- no change was needed + * SASL_NOUSER -- no entry for user + * SASL_NOVERIFY -- no mechanism compatible entry for user + * SASL_PWLOCK -- password locked + * SASL_DIABLED -- account disabled + * etc. + */ + int (*setpass)(void *glob_context, + sasl_server_params_t *sparams, + const char *user, + const char *pass, unsigned passlen, + const char *oldpass, unsigned oldpasslen, + unsigned flags); + + /* query which mechanisms are available for user + * glob_context -- context + * sparams -- service, middleware utilities, etc. props ignored + * user -- NUL terminated user name + * maxmech -- max number of strings in mechlist (0 = no output) + * output: + * mechlist -- an array of C string pointers, filled in with + * mechanism names available to the user + * + * returns: + * SASL_OK -- success + * SASL_NOMEM -- not enough memory + * SASL_FAIL -- lower level failure + * SASL_DISABLED -- account disabled + * SASL_NOUSER -- user not found + * SASL_BUFOVER -- maxmech is too small + * SASL_NOVERIFY -- user found, but no mechanisms available + */ + int (*user_query)(void *glob_context, + sasl_server_params_t *sparams, + const char *user, + int maxmech, + const char **mechlist); + + /* perform precalculations during a network round-trip + * or idle period. conn_context may be NULL (optional) + * returns 1 if action taken, 0 if no action taken + */ + int (*idle)(void *glob_context, + void *conn_context, + sasl_server_params_t *sparams); + + /* check if mechanism is available + * optional--if NULL, mechanism is available based on ENABLE= in config + * + * If this routine sets conn_context to a non-NULL value, then the call + * to mech_new will be skipped. This should not be done unless + * there's a significant performance benefit, since it can cause + * 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. If mech_avail returns SASL_NOTDONE, then a + * future call to mech_avail may still return either SASL_OK + * or SASL_NOMECH. + * + * returns SASL_OK on success, + * SASL_NOTDONE if mech is not available now, but may be later + * (e.g. EXTERNAL w/o auth_id) + * 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)(void); +} sasl_server_plug_t; + +#define SASL_SERVER_PLUG_VERSION 4 + +/* plug-in entry point: + * utils -- utility callback functions + * plugname -- name of plug-in (may be NULL) + * max_version -- highest server plug version supported + * returns: + * out_version -- server plug-in version of result + * pluglist -- list of mechanism plug-ins + * plugcount -- number of mechanism plug-ins + * results: + * SASL_OK -- success + * SASL_NOMEM -- failure + * SASL_BADVERS -- max_version too small + * SASL_BADPARAM -- bad config string + * ... + */ +typedef int sasl_server_plug_init_t(const sasl_utils_t *utils, + int max_version, + int *out_version, + sasl_server_plug_t **pluglist, + int *plugcount); + +/* + * add a server plug-in + */ +LIBSASL_API int sasl_server_add_plugin(const char *plugname, + sasl_server_plug_init_t *splugfunc); + + +typedef struct server_sasl_mechanism +{ + int version; + int condition; /* set to SASL_NOUSER if no available users; + set to SASL_CONTINUE if delayed plugin loading */ + char *plugname; /* for AUTHSOURCE tracking */ + const sasl_server_plug_t *plug; + char *f; /* where should i load the mechanism from? */ +} server_sasl_mechanism_t; + +typedef void sasl_server_info_callback_t (server_sasl_mechanism_t *m, + sasl_info_callback_stage_t stage, + void *rock); + + +/* Dump information about available server plugins (separate functions are + used for canon and auxprop plugins) */ +LIBSASL_API int sasl_server_plugin_info (const char *mech_list, + sasl_server_info_callback_t *info_cb, + void *info_cb_rock); + + +/********************************************************* + * 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 */ + char *name; + + /* 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)(void); + int (*spare_fptr2)(void); + int (*spare_fptr3)(void); +} 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. + */ + int (*auxprop_lookup)(void *glob_context, + sasl_server_params_t *sparams, + unsigned flags, + const char *user, unsigned ulen); + + /* name of the auxprop plugin */ + char *name; + + /* store the fields/values of an auxiliary property context (OPTIONAL) + * + * if ctx is NULL, just check if storing properties is enabled + * + * returns + * SASL_OK on success + * SASL_FAIL on failure + */ + int (*auxprop_store)(void *glob_context, + sasl_server_params_t *sparams, + struct propctx *ctx, + const char *user, unsigned ulen); +} 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_AUTHZID 0x02 /* if clear, we are looking up the + * authid flags (prefixed with *), otherwise + * we are looking up the authzid flags + * (no prefix) */ + +/* NOTE: Keep in sync with SASL_CU_<XXX> flags */ +#define SASL_AUXPROP_VERIFY_AGAINST_HASH 0x10 + + +#define SASL_AUXPROP_PLUG_VERSION 8 + +/* 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); + +typedef void auxprop_info_callback_t (sasl_auxprop_plug_t *m, + sasl_info_callback_stage_t stage, + void *rock); + +/* Dump information about available auxprop plugins (separate functions are + used for canon and server authentication plugins) */ +LIBSASL_API int auxprop_plugin_info (const char *mech_list, + auxprop_info_callback_t *info_cb, + void *info_cb_rock); + +#ifdef __cplusplus +} +#endif + +#endif /* SASLPLUG_H */ diff --git a/contrib/libs/sasl/include/saslutil.h b/contrib/libs/sasl/include/saslutil.h new file mode 100644 index 0000000000..e0fa47c591 --- /dev/null +++ b/contrib/libs/sasl/include/saslutil.h @@ -0,0 +1,99 @@ +/* saslutil.h -- various utility functions in SASL library + */ + +#ifndef SASLUTIL_H +#define SASLUTIL_H 1 + +#ifndef SASL_H +#include "sasl.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* base64 decode + * in -- input data + * inlen -- length of input data + * out -- output data (may be same as in, must have enough space) + * outmax -- max size of output buffer + * result: + * outlen -- actual output length + * + * returns SASL_BADPROT on bad base64, + * SASL_BUFOVER if result won't fit + * SASL_OK on success + */ +LIBSASL_API int sasl_decode64(const char *in, unsigned inlen, + char *out, unsigned outmax, unsigned *outlen); + +/* base64 encode + * in -- input data + * inlen -- input data length + * out -- output buffer (will be NUL terminated) + * outmax -- max size of output buffer + * result: + * outlen -- gets actual length of output buffer (optional) + * + * Returns SASL_OK on success, SASL_BUFOVER if result won't fit + */ +LIBSASL_API int sasl_encode64(const char *in, unsigned inlen, + char *out, unsigned outmax, unsigned *outlen); + +/* make a challenge string (NUL terminated) + * buf -- buffer for result + * maxlen -- max length of result + * hostflag -- 0 = don't include hostname, 1 = include hostname + * returns final length or 0 if not enough space + */ +LIBSASL_API int sasl_mkchal(sasl_conn_t *conn, char *buf, + unsigned maxlen, unsigned hostflag); + +/* verify a string is valid UTF-8 + * if len == 0, strlen(str) will be used. + * returns SASL_BADPROT on error, SASL_OK on success + */ +LIBSASL_API int sasl_utf8verify(const char *str, unsigned len); + +/* create random pool seeded with OS-based params */ +LIBSASL_API int sasl_randcreate(sasl_rand_t **rpool); + +/* free random pool from randcreate */ +LIBSASL_API void sasl_randfree(sasl_rand_t **rpool); + +/* seed random number generator */ +LIBSASL_API void sasl_randseed(sasl_rand_t *rpool, const char *seed, + unsigned len); + +/* generate random octets */ +LIBSASL_API void sasl_rand(sasl_rand_t *rpool, char *buf, unsigned len); + +/* churn data into random number generator */ +LIBSASL_API void sasl_churn(sasl_rand_t *rpool, const char *data, + unsigned len); + +/* erase a security sensitive buffer or password. + * Implementation may use recovery-resistant erase logic. + */ +LIBSASL_API void sasl_erasebuffer(char *pass, unsigned len); + +/* Lowercase string in place */ +LIBSASL_API char *sasl_strlower (char *val); + +LIBSASL_API int sasl_config_init(const char *filename); + +LIBSASL_API void sasl_config_done(void); + +#ifdef WIN32 +/* Just in case a different DLL defines this as well */ +#if defined(NEED_GETOPT) +LIBSASL_API int getopt(int argc, char **argv, char *optstring); +#endif +LIBSASL_API char * getpass(const char *prompt); +#endif /* WIN32 */ + +#ifdef __cplusplus +} +#endif + +#endif /* SASLUTIL_H */ |