diff options
author | stevel@tonic-gate <none@none> | 2005-06-14 00:00:00 -0700 |
---|---|---|
committer | stevel@tonic-gate <none@none> | 2005-06-14 00:00:00 -0700 |
commit | 7c478bd95313f5f23a4c958a745db2134aa03244 (patch) | |
tree | c871e58545497667cbb4b0a4f2daf204743e1fe7 /usr/src/lib/libsasl/include | |
download | illumos-joyent-7c478bd95313f5f23a4c958a745db2134aa03244.tar.gz |
OpenSolaris Launch
Diffstat (limited to 'usr/src/lib/libsasl/include')
-rw-r--r-- | usr/src/lib/libsasl/include/config.h | 496 | ||||
-rw-r--r-- | usr/src/lib/libsasl/include/hmac-md5.h | 64 | ||||
-rw-r--r-- | usr/src/lib/libsasl/include/md5_private.h | 56 | ||||
-rw-r--r-- | usr/src/lib/libsasl/include/md5global.h | 40 | ||||
-rw-r--r-- | usr/src/lib/libsasl/include/plugin_common.h | 226 | ||||
-rw-r--r-- | usr/src/lib/libsasl/include/prop.h | 182 | ||||
-rw-r--r-- | usr/src/lib/libsasl/include/sasl.h | 1276 | ||||
-rw-r--r-- | usr/src/lib/libsasl/include/saslplug.h | 892 | ||||
-rw-r--r-- | usr/src/lib/libsasl/include/saslutil.h | 105 |
9 files changed, 3337 insertions, 0 deletions
diff --git a/usr/src/lib/libsasl/include/config.h b/usr/src/lib/libsasl/include/config.h new file mode 100644 index 0000000000..dab7267576 --- /dev/null +++ b/usr/src/lib/libsasl/include/config.h @@ -0,0 +1,496 @@ +/* + * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +/* + * Copyright (c) 1998-2003 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 + * Office of Technology Transfer + * Carnegie Mellon University + * 5000 Forbes Avenue + * Pittsburgh, PA 15213-3890 + * (412) 268-4387, fax: (412) 268-7395 + * tech-transfer@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. + */ + +#ifndef CONFIG_H +#define CONFIG_H + +#include <sys/types.h> + +/* Define to empty if the keyword does not work. */ +/* #undef const */ + +/* Define if you have <sys/wait.h> that is POSIX.1 compatible. */ +#define HAVE_SYS_WAIT_H 1 + +/* Define as __inline if that's what the C compiler calls it. */ +/* #undef inline */ + +/* Define to `int' if <sys/types.h> doesn't define. */ +/* #undef mode_t */ + +/* Define to `int' if <sys/types.h> doesn't define. */ +/* #undef pid_t */ + +/* Define as the return type of signal handlers (int or void). */ +#define RETSIGTYPE void + +/* Define if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define if you can safely include both <sys/time.h> and <time.h>. */ +#define TIME_WITH_SYS_TIME 1 + +/* Set to the database name you want SASL to use for + * username->secret lookups */ +/* #undef SASL_DB_PATH */ + +/* what db package are we using? */ +/* #undef SASL_GDBM */ +/* #undef SASL_NDBM */ +/* #undef SASL_BERKELEYDB */ + +/* which mechs can we link staticly? */ +/* #undef STATIC_ANONYMOUS */ +/* #undef STATIC_CRAMMD5 */ +/* #undef STATIC_DIGESTMD5 */ +/* #undef STATIC_GSSAPIV2 */ +/* #undef STATIC_KERBEROS4 */ +/* #undef STATIC_LOGIN */ +/* #undef STATIC_MYSQL */ +/* #undef STATIC_NTLM */ +/* #undef STATIC_OTP */ +/* #undef STATIC_PLAIN */ +/* #undef STATIC_SASLDB */ +/* #undef STATIC_SRP */ + +/* This is where plugins will live at runtime */ +#ifdef _LP64 +#if defined(__sparcv9) +#define PLUGINDIR "/usr/lib/sasl/sparcv9" +#elif defined(__amd64) +#define PLUGINDIR "/usr/lib/sasl/amd64" +#else +#error Unsupported 64-bit architecture! +#endif +#else +#define PLUGINDIR "/usr/lib/sasl" +#endif + +#define SASL_CONFDIR "/etc/sasl" + +/* should we use the internal rc4 library? */ +/* This may be defined in digestmd5 makefile */ +/* #undef WITH_RC4 */ + +/* do we have des available? */ +/* This may be defined in digestmd5 makefile */ +/* #undef WITH_DES */ +/* #undef WITH_SSL_DES */ + +/* what about OpenSSL? */ +/* #undef HAVE_OPENSSL */ + +/* should we support srp_setpass */ +/* #undef DO_SRP_SETPASS */ + +/* do we have OPIE for server-side OTP support? */ +/* #undef HAVE_OPIE */ + +/* Do we have kerberos for plaintext password checking? */ +/* #undef HAVE_KRB */ + +/* do we have PAM for plaintext password checking? */ +#define HAVE_PAM 1 + +/* do we have getsubopt()? */ +#define HAVE_GETSUBOPT 1 + +/* Does your system have the snprintf() call? */ +#define HAVE_SNPRINTF 1 + +/* Does your system have the vsnprintf() call? */ +#define HAVE_VSNPRINTF 1 + +/* should we include support for the pwcheck daemon? */ +/* #undef HAVE_PWCHECK */ + +/* where do we look for the pwcheck daemon? */ +/* #undef PWCHECKDIR */ + +/* should we include support for the saslauth daemon? */ +/* #undef HAVE_SASLAUTHD */ + +/* where does saslauthd look for the communication socket? */ +/* #undef PATH_SASLAUTHD_RUNDIR */ + +/* do we want alwaystrue (discouraged)? */ +/* #undef HAVE_ALWAYSTRUE */ + +/* are we linking against DMALLOC? */ +/* #undef WITH_DMALLOC */ + +/* should we support sasl_checkapop */ +#define DO_SASL_CHECKAPOP 1 + +/* do we pay attention to IP addresses in the kerberos 4 tickets? */ +/* #undef KRB4_IGNORE_IP_ADDRESS */ + +/* do we have a preferred mechanism, or should we just pick the highest ssf? */ +/* #undef PREFER_MECH */ + +/* Do we need a leading _ for dlsym? */ +/* #undef DLSYM_NEEDS_UNDERSCORE */ + +/* Does libtool support shared libs on this system? */ +#define HAVE_DLFCN_H 1 +#define DO_DLOPEN 1 + +/* Should we try to dlopen stuff when we are staticly compiled? */ +/* #undef TRY_DLOPEN_WHEN_STATIC */ + +/* define if your system has getaddrinfo() */ +#define HAVE_GETADDRINFO 1 +#define HAVE_INET_ATON 1 + +/* define if your system has getnameinfo() */ +#define HAVE_GETNAMEINFO 1 + +/* define if your system has struct sockaddr_storage */ +#define HAVE_STRUCT_SOCKADDR_STORAGE 1 + +/* Define if you have ss_family in struct sockaddr_storage. */ +#define HAVE_SS_FAMILY 1 + +/* do we have socklen_t? */ +#define HAVE_SOCKLEN_T 1 + +/* #undef HAVE_SOCKADDR_SA_LEN */ + +/* do we use doors for IPC? */ +/* #undef USE_DOORS */ + +/* Define if you have the dn_expand function. */ +#define HAVE_DN_EXPAND 1 + +/* Define if you have the dns_lookup function. */ +/* #undef HAVE_DNS_LOOKUP */ + +/* Define if you have the getdomainname function. */ +/* #undef HAVE_GETDOMAINNAME */ + +/* Define if you have the gethostname function. */ +#define HAVE_GETHOSTNAME 1 + +/* Define if you have the getpwnam function. */ +#define HAVE_GETPWNAM 1 + +/* Define if you have the getspnam function. */ +#define HAVE_GETSPNAM 1 + +/* Define if you have the gettimeofday function. */ +#define HAVE_GETTIMEOFDAY 1 + +/* Define if you have the gsskrb5_register_acceptor_identity function. */ +/* #undef HAVE_GSSKRB5_REGISTER_ACCEPTOR_IDENTITY */ + +/* Define if you have the jrand48 function. */ +#define HAVE_JRAND48 1 + +/* Define if you have the krb_get_err_text function. */ +/* #undef HAVE_KRB_GET_ERR_TEXT */ + +/* Define if you have the memcpy function. */ +#define HAVE_MEMCPY 1 + +/* Define if you have the mkdir function. */ +#define HAVE_MKDIR 1 + +/* Define if you have the select function. */ +#define HAVE_SELECT 1 + +/* Define if you have the socket function. */ +#define HAVE_SOCKET 1 + +/* Define if you have the strchr function. */ +#define HAVE_STRCHR 1 + +/* Define if you have the strdup function. */ +#define HAVE_STRDUP 1 + +/* Define if you have the strerror function. */ +#define HAVE_STRERROR 1 + +/* Define if you have the strspn function. */ +#define HAVE_STRSPN 1 + +/* Define if you have the strstr function. */ +#define HAVE_STRSTR 1 + +/* Define if you have the strtol function. */ +#define HAVE_STRTOL 1 + +/* Define if you have the syslog function. */ +#define HAVE_SYSLOG 1 + +/* Define if you have the <dirent.h> header file. */ +#define HAVE_DIRENT_H 1 + +/* Define if you have the <dlfcn.h> header file. */ +#define HAVE_DLFCN_H 1 + +/* Define if you have the <fcntl.h> header file. */ +#define HAVE_FCNTL_H 1 + +/* Define if you have the <inttypes.h> header file. */ +#define HAVE_INTTYPES_H 1 + +/* Define if you have the <limits.h> header file. */ +#define HAVE_LIMITS_H 1 + +/* Define if you have the <malloc.h> header file. */ +#define HAVE_MALLOC_H 1 + +/* Define if you have the <ndir.h> header file. */ +/* #undef HAVE_NDIR_H */ + +/* Define if you have the <paths.h> header file. */ +/* #undef HAVE_PATHS_H */ + +/* Define if you have the <stdarg.h> header file. */ +#define HAVE_STDARG_H 1 + +/* Define if you have the <strings.h> header file. */ +#define HAVE_STRINGS_H 1 + +/* Define if you have the <sys/dir.h> header file. */ +/* #undef HAVE_SYS_DIR_H */ + +/* Define if you have the <sys/file.h> header file. */ +#define HAVE_SYS_FILE_H 1 + +/* Define if you have the <sys/ndir.h> header file. */ +/* #undef HAVE_SYS_NDIR_H */ + +/* Define if you have the <sys/param.h> header file. */ +#define HAVE_SYS_PARAM_H 1 + +/* Define if you have the <sys/time.h> header file. */ +#define HAVE_SYS_TIME_H 1 + +/* Define if you have the <sys/uio.h> header file. */ +#define HAVE_SYS_UIO_H 1 + +/* Define if you have the <sysexits.h> header file. */ +#define HAVE_SYSEXITS_H 1 + +/* Define if you have the <syslog.h> header file. */ +#define HAVE_SYSLOG_H 1 + +/* Define if you have the <unistd.h> header file. */ +#define HAVE_UNISTD_H 1 + +/* Define if you have the <varargs.h> header file. */ +#define HAVE_VARARGS_H 1 + +/* Define if you have the db library (-ldb). */ +/* #undef HAVE_LIBDB */ + +/* Define if you have the resolv library (-lresolv). */ +#define HAVE_LIBRESOLV 1 + +/* Name of package */ +/* #define PACKAGE "cyrus-sasl" */ + +/* Version number of package */ +/* #undef VERSION */ + +/* define if your compiler has __attribute__ */ +/* #undef HAVE___ATTRIBUTE__ */ + +/* Define if you have the gssapi.h header file */ +/* #undef HAVE_GSSAPI_H */ + +/* Define if your GSSAPI implimentation defines GSS_C_NT_HOSTBASED_SERVICE */ +#define HAVE_GSS_C_NT_HOSTBASED_SERVICE + + +/* Create a struct iovec if we need one */ +#if !defined(_WIN32) && !defined(HAVE_SYS_UIO_H) +/* (win32 is handled in sasl.h) */ +struct iovec { + char *iov_base; + long iov_len; +}; +#else +#include <sys/uio.h> +#endif + +/* location of the random number generator */ +#ifndef DEV_RANDOM +#define DEV_RANDOM "/dev/urandom" +#endif +#define _DEV_URANDOM "/dev/urandom" + +/* if we've got krb_get_err_txt, we might as well use it; + especially since krb_err_txt isn't in some newer distributions + (MIT Kerb for Mac 4 being a notable example). If we don't have + it, we fall back to the krb_err_txt array */ +#ifdef HAVE_KRB_GET_ERR_TEXT +#define get_krb_err_txt krb_get_err_text +#else +#define get_krb_err_txt(X) (krb_err_txt[(X)]) +#endif + +/* Make Solaris happy... */ +#ifndef __EXTENSIONS__ +#define __EXTENSIONS__ +#endif + +/* Make Linux happy... */ +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif + +#ifndef HAVE___ATTRIBUTE__ +/* Can't use attributes... */ +#define __attribute__(foo) +#endif + +#define SASL_PATH_ENV_VAR "SASL_PATH" + +#include <stdlib.h> +#include <sys/socket.h> +#ifndef WIN32 +# include <netdb.h> +# ifdef HAVE_SYS_PARAM_H +# include <sys/param.h> +# endif +#else /* WIN32 */ +# include <winsock.h> +#endif /* WIN32 */ + +#include <string.h> + +#include <netinet/in.h> + +#ifndef HAVE_STRUCT_SOCKADDR_STORAGE +#define _SS_MAXSIZE 128 /* Implementation specific max size */ +#define _SS_PADSIZE (_SS_MAXSIZE - sizeof (struct sockaddr)) + +struct sockaddr_storage { + struct sockaddr ss_sa; + char __ss_pad2[_SS_PADSIZE]; +}; +# define ss_family ss_sa.sa_family +#endif /* !HAVE_STRUCT_SOCKADDR_STORAGE */ + +#ifndef AF_INET6 +/* Define it to something that should never appear */ +#define AF_INET6 AF_MAX +#endif + +#ifndef HAVE_GETADDRINFO +#define getaddrinfo sasl_getaddrinfo +#define freeaddrinfo sasl_freeaddrinfo +#define getnameinfo sasl_getnameinfo +#define gai_strerror sasl_gai_strerror +#include "gai.h" +#endif + +/* Defined in RFC 1035. max strlen is only 253 due to length bytes. */ +#ifndef MAXHOSTNAMELEN +#define MAXHOSTNAMELEN 255 +#endif + +#ifndef HAVE_SYSEXITS_H +#include "exits.h" +#else +#include "sysexits.h" +#endif + +#ifndef NI_WITHSCOPEID +#define NI_WITHSCOPEID 0 +#endif + +/* Get the correct time.h */ +#if TIME_WITH_SYS_TIME +# include <sys/time.h> +# include <time.h> +#else +# if HAVE_SYS_TIME_H +# include <sys/time.h> +# else +# include <time.h> +# endif +#endif + +#include <libintl.h> +/* + * We use gettext() so that xgettext will build msg database. libsasl and + * plugins will actually use dgettext in the appropriate subroutine - + * depending on SASL_CB_LANGUAGE or the specified language. + */ +#define gettext(x) (x) + +#define USE_PTHREADS 1 +#include <pthread.h> +#define DEFINE_STATIC_MUTEX(x) \ + static pthread_mutex_t x = PTHREAD_MUTEX_INITIALIZER + +#define LOCK_MUTEX(x) pthread_mutex_lock(x) +#define UNLOCK_MUTEX(x) pthread_mutex_unlock(x) + +#define DO_DLOPEN 1 +#define TRY_DLOPEN_WHEN_STATIC 1 +#define HAVE_DLFCN_H 1 + +/* HAVE_GSS_C_NT_USER_NAME is not needed for Solaris 10 since libgss has been + * updated. + */ +#undef HAVE_GSS_C_NT_USER_NAME + +#define HAVE_RPC_GSS_MECH_TO_OID 1 + +#define _SUN_SDK_ 1 + +#define _INTEGRATED_SOLARIS_ 1 +#define _HAVE_LIB_MD5 1 + +#include "md5global.h" +#include "md5_private.h" + +#endif /* CONFIG_H */ diff --git a/usr/src/lib/libsasl/include/hmac-md5.h b/usr/src/lib/libsasl/include/hmac-md5.h new file mode 100644 index 0000000000..9f9e907a9f --- /dev/null +++ b/usr/src/lib/libsasl/include/hmac-md5.h @@ -0,0 +1,64 @@ +/* + * Copyright 2003 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +/* hmac-md5.h -- HMAC_MD5 functions + */ + +#ifndef HMAC_MD5_H +#define HMAC_MD5_H 1 + +#define HMAC_MD5_SIZE 16 + +#ifdef _SUN_SDK_ +#ifndef SASLPLUG_H +#include <sasl/saslplug.h> +#endif +#else +/* 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 { + UINT4 istate[4]; + UINT4 ostate[4]; +} HMAC_MD5_STATE; +#endif /* _SUN_SDK */ + +/* 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); + +#endif /* HMAC_MD5_H */ diff --git a/usr/src/lib/libsasl/include/md5_private.h b/usr/src/lib/libsasl/include/md5_private.h new file mode 100644 index 0000000000..0b77ffbb16 --- /dev/null +++ b/usr/src/lib/libsasl/include/md5_private.h @@ -0,0 +1,56 @@ +/* + * Copyright 2003 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +/* 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. + */ + +#ifndef _MD5_PRIVATE_H +#define _MD5_PRIVATE_H + +#ifdef _SUN_SDK_ +#ifndef _MD5_H +#include <md5.h> +#endif /* _MD5_H */ + +#define _sasl_MD5Init(md5_ctx) MD5Init(md5_ctx) +#define _sasl_MD5Update(md5_ctx, s, n) MD5Update(md5_ctx, s, n) +#define _sasl_MD5Final(b, md5_ctx) MD5Final(b, md5_ctx) +#else +/* MD5 context. */ +typedef struct { + UINT4 state[4]; /* state (ABCD) */ + UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */ + unsigned char buffer[64]; /* input buffer */ +} MD5_CTX; + +void _sasl_MD5Init PROTO_LIST ((MD5_CTX *)); +void _sasl_MD5Update PROTO_LIST + ((MD5_CTX *, unsigned char *, unsigned int)); +void _sasl_MD5Final PROTO_LIST ((unsigned char [16], MD5_CTX *)); + +void _sasl_hmac_md5 PROTO_LIST ((unsigned char *, int, unsigned char *, int, caddr_t)); +#endif /* _SUN_SDK_ */ + +#endif /* _MD5_PRIVATE_H */ diff --git a/usr/src/lib/libsasl/include/md5global.h b/usr/src/lib/libsasl/include/md5global.h new file mode 100644 index 0000000000..5266bbb218 --- /dev/null +++ b/usr/src/lib/libsasl/include/md5global.h @@ -0,0 +1,40 @@ +#pragma ident "%Z%%M% %I% %E% SMI" + +/* md5global.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 INT1; /* 8 bits */ +typedef short INT2; /* 16 bits */ +typedef int INT4; /* 32 bits */ +/* There is no 64 bit type */ +typedef unsigned char UINT1; /* 8 bits */ +typedef unsigned short UINT2; /* 16 bits */ +typedef unsigned int UINT4; /* 32 bits */ +/* There is no 64 bit type */ + +/* 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/usr/src/lib/libsasl/include/plugin_common.h b/usr/src/lib/libsasl/include/plugin_common.h new file mode 100644 index 0000000000..f10da39db5 --- /dev/null +++ b/usr/src/lib/libsasl/include/plugin_common.h @@ -0,0 +1,226 @@ +/* + * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ +#pragma ident "%Z%%M% %I% %E% SMI" + +/* Generic SASL plugin utility functions + * Rob Siemborski + * $Id: plugin_common.h,v 1.16 2003/04/07 16:03:43 rjs3 Exp $ + */ + +/* + * Copyright (c) 1998-2003 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 + * Office of Technology Transfer + * Carnegie Mellon University + * 5000 Forbes Avenue + * Pittsburgh, PA 15213-3890 + * (412) 268-4387, fax: (412) 268-7395 + * tech-transfer@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. + */ + +#ifndef _PLUGIN_COMMON_H_ +#define _PLUGIN_COMMON_H_ + +#include <config.h> + +#ifndef macintosh +#ifdef WIN32 +# include <winsock.h> +#else +# include <sys/socket.h> +# include <netinet/in.h> +# include <arpa/inet.h> +# include <netdb.h> +#endif /* WIN32 */ +#endif /* macintosh */ + +#include <sasl.h> +#include <saslutil.h> +#include <saslplug.h> + +#ifdef WIN32 +#define PLUG_API __declspec(dllexport) +#else +#define PLUG_API extern +#endif + +#define SASL_CLIENT_PLUG_INIT( x ) \ +extern sasl_client_plug_init_t x##_client_plug_init; \ +PLUG_API int sasl_client_plug_init(const sasl_utils_t *utils, \ + int maxversion, int *out_version, \ + sasl_client_plug_t **pluglist, \ + int *plugcount) { \ + return x##_client_plug_init(utils, maxversion, out_version, \ + pluglist, plugcount); \ +} + +#define SASL_SERVER_PLUG_INIT( x ) \ +extern sasl_server_plug_init_t x##_server_plug_init; \ +PLUG_API int sasl_server_plug_init(const sasl_utils_t *utils, \ + int maxversion, int *out_version, \ + sasl_server_plug_t **pluglist, \ + int *plugcount) { \ + return x##_server_plug_init(utils, maxversion, out_version, \ + pluglist, plugcount); \ +} + +#define SASL_AUXPROP_PLUG_INIT( x ) \ +extern sasl_auxprop_init_t x##_auxprop_plug_init; \ +PLUG_API int sasl_auxprop_plug_init(const sasl_utils_t *utils, \ + int maxversion, int *out_version, \ + sasl_auxprop_plug_t **plug, \ + const char *plugname) {\ + return x##_auxprop_plug_init(utils, maxversion, out_version, \ + plug, plugname); \ +} + +#define SASL_CANONUSER_PLUG_INIT( x ) \ +extern sasl_canonuser_init_t x##_canonuser_plug_init; \ +PLUG_API int sasl_canonuser_init(const sasl_utils_t *utils, \ + int maxversion, int *out_version, \ + sasl_canonuser_plug_t **plug, \ + const char *plugname) {\ + return x##_canonuser_plug_init(utils, maxversion, out_version, \ + plug, plugname); \ +} + +/* note: msg cannot include additional variables, so if you want to + * do a printf-format string, then you need to call seterror yourself */ +#define SETERROR( utils, msg ) (utils)->seterror( (utils)->conn, 0, (msg) ) + +#ifndef MEMERROR +#ifdef _SUN_SDK_ +#define MEMERROR( utils ) \ + (utils)->seterror( (utils)->conn, 0, "Out of Memory") +#else +#define MEMERROR( utils ) \ + (utils)->seterror( (utils)->conn, 0, \ + "Out of Memory in " __FILE__ " near line %d", __LINE__ ) +#endif /* _SUN_SDK_ */ +#endif + +#ifndef PARAMERROR +#ifdef _SUN_SDK_ +#define PARAMERROR( utils ) \ + (utils)->seterror( (utils)->conn, 0, "Parameter Error") +#else +#define PARAMERROR( utils ) \ + (utils)->seterror( (utils)->conn, 0, \ + "Parameter Error in " __FILE__ " near line %d", __LINE__ ) +#endif /* _SUN_SDK_ */ +#endif + +#ifndef SASLINT_H +typedef struct buffer_info +{ + char *data; + unsigned curlen; /* Current length of data in buffer */ + unsigned reallen; /* total length of buffer (>= curlen) */ +} buffer_info_t; +#endif + +int _plug_ipfromstring(const sasl_utils_t *utils, const char *addr, + struct sockaddr *out, socklen_t outlen); +int _plug_iovec_to_buf(const sasl_utils_t *utils, const struct iovec *vec, + unsigned numiov, buffer_info_t **output); +int _plug_buf_alloc(const sasl_utils_t *utils, char **rwbuf, + unsigned *curlen, unsigned newlen); +int _plug_strdup(const sasl_utils_t * utils, const char *in, + char **out, int *outlen); +void _plug_free_string(const sasl_utils_t *utils, char **str); +void _plug_free_secret(const sasl_utils_t *utils, sasl_secret_t **secret); + +#define _plug_get_userid(utils, result, prompt_need) \ + _plug_get_simple(utils, SASL_CB_USER, 0, result, prompt_need) +#define _plug_get_authid(utils, result, prompt_need) \ + _plug_get_simple(utils, SASL_CB_AUTHNAME, 1, result, prompt_need) +int _plug_get_simple(const sasl_utils_t *utils, unsigned int id, int required, + const char **result, sasl_interact_t **prompt_need); + +int _plug_get_password(const sasl_utils_t *utils, sasl_secret_t **secret, + unsigned int *iscopy, sasl_interact_t **prompt_need); + +int _plug_challenge_prompt(const sasl_utils_t *utils, unsigned int id, + const char *challenge, const char *promptstr, + const char **result, sasl_interact_t **prompt_need); + +int _plug_get_realm(const sasl_utils_t *utils, const char **availrealms, + const char **realm, sasl_interact_t **prompt_need); + +int _plug_make_prompts(const sasl_utils_t *utils, +#ifdef _INTEGRATED_SOLARIS_ + void **h, +#endif /* _INTEGRATED_SOLARIS_ */ + sasl_interact_t **prompts_res, + const char *user_prompt, const char *user_def, + const char *auth_prompt, const char *auth_def, + const char *pass_prompt, const char *pass_def, + const char *echo_chal, + const char *echo_prompt, const char *echo_def, + const char *realm_chal, + const char *realm_prompt, const char *realm_def); + +int _plug_decode(const sasl_utils_t *utils, + void *context, + const char *input, unsigned inputlen, + char **output, unsigned *outputsize, unsigned *outputlen, + int (*decode_pkt)(void *context, + const char **input, unsigned *inputlen, + char **output, unsigned *outputlen)); + +int _plug_parseuser(const sasl_utils_t *utils, + char **user, char **realm, const char *user_realm, + const char *serverFQDN, const char *input); + +#ifdef _INTEGRATED_SOLARIS_ +/* EXPORT DELETE START */ +/* CRYPT DELETE START */ +typedef void reg_sun_t(void *); + +#define REG_PLUG( X, Y ) { \ + reg_sun_t *func = NULL; \ + unsigned int l; \ + utils->getopt(utils->getopt_context, X, "reg_sun_plug", \ + (const char **)&func, &l); \ + if (func != NULL && l == 0) \ + (*func)(Y); \ +} +/* CRYPT DELETE END */ +/* EXPORT DELETE END */ + +int use_locale(const char *lang_list, int is_client); +const char *convert_prompt(const sasl_utils_t *utils, void **h, const char *s); +char *local_to_utf(const sasl_utils_t *utils, const char *s); +#endif /* _INTEGRATED_SOLARIS_ */ +#endif /* _PLUGIN_COMMON_H_ */ diff --git a/usr/src/lib/libsasl/include/prop.h b/usr/src/lib/libsasl/include/prop.h new file mode 100644 index 0000000000..e74bf07fb4 --- /dev/null +++ b/usr/src/lib/libsasl/include/prop.h @@ -0,0 +1,182 @@ +/* + * Copyright 2003 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +/* + * 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 _SASL_PROP_H +#define _SASL_PROP_H + +#pragma ident "%Z%%M% %I% %E% SMI" + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * the resulting structure for property values + */ +struct propval { + /* + * name of property; NULL = end of list + * same pointer used in request will be used here + */ + const char *name; + 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; + +/* + * 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 + */ +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 + */ +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 + */ +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 + */ +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 + */ +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 + */ +void prop_clear(struct propctx *ctx, int requests); + +/* + * erase the value of a property + */ +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 + */ +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 + */ +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 + */ +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 + */ +int prop_setvals(struct propctx *ctx, const char *name, + const char **values); + + +#ifdef __cplusplus +} +#endif + +#endif /* _SASL_PROP_H */ diff --git a/usr/src/lib/libsasl/include/sasl.h b/usr/src/lib/libsasl/include/sasl.h new file mode 100644 index 0000000000..fbaa9a55f2 --- /dev/null +++ b/usr/src/lib/libsasl/include/sasl.h @@ -0,0 +1,1276 @@ +/* + * Copyright 2003 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +/* + * *******************************IMPORTANT****************************** + * send email to chris.newman@sun.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_canon_user_t client/server: Canonicalize username + * sasl_log_t client/server: Log message handler + * sasl_verifyfile_t client/server: Verify file for specified usage + * sasl_getpath_t client/server: Get sasl search path + * + * Client only Callbacks: + * sasl_getrealm_t client: Get available realms + * 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_server_userdb_checkpass_t check password and auxprops in userdb + * sasl_server_userdb_setpass_t set password in userdb + * + * 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 + * + * 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_SASL_H +#define _SASL_SASL_H + +#pragma ident "%Z%%M% %I% %E% SMI" + +#ifndef _SASL_PROP_H +#include <sasl/prop.h> +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#define SASL_VERSION_MAJOR 2 +#define SASL_VERSION_MINOR 1 +#define SASL_VERSION_STEP 15 + +/* + * 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.) + */ +#ifdef WIN32 +#ifdef LIBSASL_EXPORTS +#define LIBSASL_API __declspec(dllexport) +#else /* LIBSASL_EXPORTS */ +#define LIBSASL_API __declspec(dllimport) +#endif /* LIBSASL_EXPORTS */ +#else /* WIN32 */ +#define LIBSASL_API extern +#endif /* WIN32 */ + +/* + * Same as above, but used during a variable declaration. Only Unix definition + * is different, as we can't assign an initial value to an extern variable + */ +#ifdef WIN32 +#ifdef LIBSASL_EXPORTS +#define LIBSASL_VAR __declspec(dllexport) +#else /* LIBSASL_EXPORTS */ +#define LIBSASL_VAR __declspec(dllimport) +#endif /* LIBSASL_EXPORTS */ +#else /* WIN32 */ +#define LIBSASL_VAR +#endif /* WIN32 */ + +/* + * 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 */ + +/* 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; + + +/* + * Configure Basic Services + */ + +/* + * the following functions are used to adjust how allocation and mutexes work + * they must be called before all other SASL functions: + */ + +/* The following function is obsolete */ +/* + * memory allocation functions which may optionally be replaced: + */ +typedef void *sasl_malloc_t(unsigned long); +typedef void *sasl_calloc_t(unsigned long, unsigned long); +typedef void *sasl_realloc_t(void *, unsigned long); +typedef void sasl_free_t(void *); + +LIBSASL_API void sasl_set_alloc(sasl_malloc_t *, + sasl_calloc_t *, + sasl_realloc_t *, + sasl_free_t *); + +/* The following function is obsolete */ +/* + * 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 */ + +/* + * 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 0x00FF + +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)(); /* 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 + +/* Callback to get the location of the sasl config */ +#define SASL_CB_GETCONF 0x5001 + +/* + * 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 + + +/* 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 + +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 + */ + +/* + * get sasl library version information + * implementation is a vendor-defined string + * version is a vender-defined representation of the version # + */ +LIBSASL_API void sasl_version(const char **implementation, + int *version); + +/* + * dispose of all SASL plugins. Connection + * states have to be disposed of before calling this. + */ +LIBSASL_API void sasl_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 */ +#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 */ + +/* + * This returns a string which is either empty or has an error message + * from sasl_seterror (e.g., from a plug-in or callback). It differs + * from the result of sasl_errdetail() which also takes into account the + * last return status code. + */ +#define SASL_PLUGERR 10 + +/* + * set property in SASL connection state + * 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) + * out: + * pconn -- sasl connection + * + * 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 -- list of mechanisms to use (punctuation ignored) + * 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); + +/* The following function is obsolete */ +/* + * 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); + +/* The following function is obsolete */ +/* + * 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 + */ +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_REMOVE SASL_SET_CREATE /* remove user if pass is NULL */ +#define SASL_SET_DISABLE 0x02 /* disable user account */ + +/* + * Auxiliary Property Support -- added by cjn 1999-09-29 + */ + +#define SASL_AUX_END NULL /* last auxiliary property */ + +/* traditional Posix items (should be implemented on Posix systems) */ +#define SASL_AUX_PASSWORD "*userPassword" /* User Password (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); + +/* + * 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_SASL_H */ diff --git a/usr/src/lib/libsasl/include/saslplug.h b/usr/src/lib/libsasl/include/saslplug.h new file mode 100644 index 0000000000..6bb59e8d90 --- /dev/null +++ b/usr/src/lib/libsasl/include/saslplug.h @@ -0,0 +1,892 @@ +/* + * Copyright 2003 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +/* saslplug.h -- API for SASL plug-ins */ + +#ifndef _SASL_SASLPLUG_H +#define _SASL_SASLPLUG_H + +#pragma ident "%Z%%M% %I% %E% SMI" + +#ifndef _SASL_SASL_H +#include <sasl/sasl.h> +#endif + +#ifndef _MD5_H +#include <md5.h> +#endif /* _MD5_H */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* 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 { + uint32_t istate[4]; + uint32_t ostate[4]; +} HMAC_MD5_STATE; + +/* + * 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_getcallback_t(sasl_conn_t *conn, + unsigned long callbackid, + int (**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 most recent errno + * error). 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, ...); + + /* callback to sasl_seterror() */ + void (*seterror)(sasl_conn_t *conn, unsigned flags, const char *fmt, ...); + + /* spare function pointer */ + int *(*spare_fptr)(); + + /* auxiliary property utilities */ + struct propctx *(*prop_new)(unsigned estimate); + int (*prop_dup)(struct propctx *src_ctx, struct propctx **dst_ctx); + int (*prop_request)(struct propctx *ctx, const char **names); + const struct propval *(*prop_get)(struct propctx *ctx); + int (*prop_getnames)(struct propctx *ctx, const char **names, + struct propval *vals); + void (*prop_clear)(struct propctx *ctx, int requests); + void (*prop_dispose)(struct propctx **ctx); + int (*prop_format)(struct propctx *ctx, const char *sep, int seplen, + char *outbuf, unsigned outmax, unsigned *outlen); + int (*prop_set)(struct propctx *ctx, const char *name, + const char *value, int vallen); + int (*prop_setvals)(struct propctx *ctx, const char *name, + const char **values); + void (*prop_erase)(struct propctx *ctx, const char *name); + + /* for additions which don't require a version upgrade; set to 0 */ + int (*spare_fptr1)(); + int (*spare_fptr2)(); + int (*spare_fptr3)(); +} sasl_utils_t; + +/* + * 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; + 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); + + /* for additions which don't require a version upgrade; set to 0 */ + void *spare_ptr1; + void *spare_ptr2; + void *spare_ptr3; + void *spare_ptr4; + int (*spare_fptr1)(); + int (*spare_fptr2)(); + int spare_int1; + int spare_int2; + int spare_int3; + 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; + +/* + * 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 */ + void *spare_ptr1; + void *spare_ptr2; + void *spare_ptr3; + void *spare_ptr4; + + /* + * Canonicalize a user name from on-wire to internal format + * added rjs3 2001-05-23 + * Must be called once user name aquired if canon_user is non-NULL. + * conn connection context + * in user name from wire protocol (need not be NUL 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)(); + + int spare_int1; + int spare_int2; + int spare_int3; + + /* flags field as passed to sasl_client_new */ + unsigned flags; + + /* + * set to 0 initially, this allows a plugin with extended parameters + * 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 take care + * of the client-first situation internally. + */ +#define SASL_FEAT_SERVER_FIRST 0x0010 + +/* This plugin allows proxying */ +#define SASL_FEAT_ALLOWS_PROXY 0x0020 + +/* 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)(); + int (*spare_fptr2)(); +} 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); + +/* + * Server Functions + */ + +/* + * 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 */ + + /* + * server plug-in calls this when it first has access to the plaintext + * passphrase. This is used to transition users via setpass calls. + * 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 aquired 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 */ + void *spare_ptr1; + void *spare_ptr2; + void *spare_ptr3; + void *spare_ptr4; + int (*spare_fptr1)(); + int (*spare_fptr2)(); + int spare_int1; + int spare_int2; + int spare_int3; + + /* flags field as passed to sasl_server_new */ + unsigned flags; + + /* + * set to 0 initially, this allows a plugin with extended parameters + * to work with an older framework by updating version as parameters + * are added. + */ + int param_version; +} sasl_server_params_t; + +/* 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 + * TODO - Is this correct? + * 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. + * + * returns SASL_OK on success, + * SASL_NOMECH if mech disabled + */ + int (*mech_avail)(void *glob_context, + sasl_server_params_t *sparams, + void **conn_context); + + /* for additions which don't require a version upgrade; set to 0 */ + int (*spare_fptr2)(); +} sasl_server_plug_t; + +#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); + +/* + * 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)(); + int (*spare_fptr2)(); + int (*spare_fptr3)(); +} sasl_canonuser_plug_t; + +#define SASL_CANONUSER_PLUG_VERSION 5 + +/* + * default name for canonuser plug-in entry point is "sasl_canonuser_init" + * similar to sasl_server_plug_init model, except only returns one + * sasl_canonuser_plug_t structure; + */ +typedef int sasl_canonuser_init_t(const sasl_utils_t *utils, + int max_version, + int *out_version, + sasl_canonuser_plug_t **plug, + const char *plugname); + +/* add a canonuser plugin */ +LIBSASL_API int sasl_canonuser_add_plugin(const char *plugname, + sasl_canonuser_init_t *canonuserfunc); + +/* + * auxiliary property plug-in -- added cjn 1999-09-29 + */ + +typedef struct sasl_auxprop_plug { + /* optional features of plugin (none defined yet, set to 0) */ + int features; + + /* spare integer, must be set to 0 */ + int spare_int1; + + /* global state for plugin */ + void *glob_context; + + /* free global state for plugin (OPTIONAL) */ + void (*auxprop_free)(void *glob_context, const sasl_utils_t *utils); + + /* + * fill in fields of an auxiliary property context + * last element in array has id of SASL_AUX_END + * elements with non-0 len should be ignored. + */ + void (*auxprop_lookup)(void *glob_context, + sasl_server_params_t *sparams, + unsigned flags, + const char *user, unsigned ulen); + + /* name of the auxprop plugin */ + char *name; + + /* for additions which don't require a version upgrade; set to 0 */ + void (*spare_fptr1)(); +} 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) */ + +#define SASL_AUXPROP_PLUG_VERSION 4 + +/* + * default name for auxprop plug-in entry point is "sasl_auxprop_init" + * similar to sasl_server_plug_init model, except only returns one + * sasl_auxprop_plug_t structure; + */ +typedef int sasl_auxprop_init_t(const sasl_utils_t *utils, + int max_version, + int *out_version, + sasl_auxprop_plug_t **plug, + const char *plugname); + +/* add an auxiliary property plug-in */ +LIBSASL_API int sasl_auxprop_add_plugin(const char *plugname, + sasl_auxprop_init_t *auxpropfunc); + +#ifdef __cplusplus +} +#endif + +#endif /* _SASL_SASLPLUG_H */ diff --git a/usr/src/lib/libsasl/include/saslutil.h b/usr/src/lib/libsasl/include/saslutil.h new file mode 100644 index 0000000000..9f2c642978 --- /dev/null +++ b/usr/src/lib/libsasl/include/saslutil.h @@ -0,0 +1,105 @@ +/* + * Copyright 2003 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +/* + * saslutil.h -- various utility functions in SASL library + */ + +#ifndef _SASL_SASLUTIL_H +#define _SASL_SASLUTIL_H + +#pragma ident "%Z%%M% %I% %E% SMI" + +#ifndef _SASL_SASL_H +#include <sasl/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); + +#if 0 +/* + * The following is not supported: + * + * 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); +#endif + +/* + * 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); + +#if 0 +/* The following are not supported */ + +/* 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); +#endif + +/* + * erase a security sensitive buffer or password. + * Implementation may use recovery-resistant erase logic. + */ +LIBSASL_API void sasl_erasebuffer(char *pass, unsigned len); + +#ifdef __cplusplus +} +#endif + +#endif /* _SASL_SASLUTIL_H */ |